package com.ruoyi.system.mapper;

import com.ruoyi.system.domain.InfoUser;
import com.ruoyi.system.domain.MerchantSubaccountStore;
import org.apache.ibatis.builder.xml.XMLMapperBuilder;
import org.apache.ibatis.mapping.ResultMapping;
import org.apache.ibatis.session.Configuration;
import org.junit.jupiter.api.Test;

import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;

class MerchantSubaccountStoreMapperXmlTest {

    @Test
    void infoUserMapsMerchantSubaccountFields() throws IOException {
        Configuration configuration = mapperConfiguration(
                "InfoUser", InfoUser.class, "mapper/infouser/InfoUserMapper.xml");

        assertColumn(configuration, "com.ruoyi.system.mapper.InfoUserMapper.InfoUserResult",
                "merchantOwnerId", "merchant_owner_id");
        assertColumn(configuration, "com.ruoyi.system.mapper.InfoUserMapper.InfoUserResult",
                "subaccountStatus", "subaccount_status");
        assertColumn(configuration, "com.ruoyi.system.mapper.InfoUserMapper.InfoUserResult",
                "lastLoginAt", "last_login_at");
    }

    @Test
    void relationMapperUsesBoundParametersAndUniqueRelationColumns() throws IOException {
        String resource = "mapper/infouser/MerchantSubaccountStoreMapper.xml";
        try (InputStream input = getClass().getClassLoader().getResourceAsStream(resource)) {
            assertNotNull(input);
            String xml = new String(input.readAllBytes(), StandardCharsets.UTF_8);
            assertTrue(xml.contains("#{subaccountUserId}"));
            assertTrue(xml.contains("#{relation.subaccountUserId}"));
            assertTrue(xml.contains("#{relation.storeId}"));
            assertTrue(xml.contains("subaccount_user_id"));
            assertTrue(xml.contains("store_id"));
        }

        mapperConfiguration("MerchantSubaccountStore", MerchantSubaccountStore.class, resource);
    }

    private void assertColumn(Configuration configuration, String resultMapId,
                              String property, String column) {
        ResultMapping mapping = configuration.getResultMap(resultMapId)
                .getResultMappings().stream()
                .filter(item -> property.equals(item.getProperty()))
                .findFirst()
                .orElseThrow();
        assertEquals(column, mapping.getColumn());
    }

    private Configuration mapperConfiguration(String alias, Class<?> type, String resource)
            throws IOException {
        Configuration configuration = new Configuration();
        configuration.getTypeAliasRegistry().registerAlias(alias, type);
        try (InputStream input = getClass().getClassLoader().getResourceAsStream(resource)) {
            assertNotNull(input);
            new XMLMapperBuilder(input, configuration, resource, configuration.getSqlFragments()).parse();
        }
        return configuration;
    }
}
