package pwc.taxtech.atms;

import java.io.InputStreamReader;
import java.io.Reader;
import java.sql.Connection;

import org.apache.ibatis.jdbc.ScriptRunner;
import org.apache.ibatis.session.SqlSessionFactory;
import org.junit.runner.RunWith;
import org.nutz.lang.Lang;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.fasterxml.jackson.databind.ObjectMapper;

import org.springframework.test.context.web.WebAppConfiguration;
import pwc.taxtech.atms.dao.*;
import pwc.taxtech.atms.entity.AreaExample;
import pwc.taxtech.atms.entity.AreaRegionExample;
import pwc.taxtech.atms.entity.CustomerExample;
import pwc.taxtech.atms.entity.EnterpriseAccountExample;
import pwc.taxtech.atms.entity.EnterpriseAccountSetExample;
import pwc.taxtech.atms.entity.EnterpriseAccountSetOrgExample;
import pwc.taxtech.atms.entity.IndustryExample;
import pwc.taxtech.atms.entity.MenuExample;
import pwc.taxtech.atms.entity.OperationLogBasicDataExample;
import pwc.taxtech.atms.entity.OperationLogEnterPriseExample;
import pwc.taxtech.atms.entity.OrganizationExample;
import pwc.taxtech.atms.entity.ProjectClientExample;
import pwc.taxtech.atms.entity.RegionExample;
import pwc.taxtech.atms.entity.ServiceTypeExample;
import pwc.taxtech.atms.entity.StandardAccountExample;
import pwc.taxtech.atms.entity.TemplateGroupExample;
import pwc.taxtech.atms.service.impl.DistributedIDService;
import pwc.taxtech.atms.vat.dao.PeriodTemplateMapper;

@WebAppConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:applicationContext.xml" })
public abstract class CommonIT {

    private static final Logger logger = LoggerFactory.getLogger(CommonIT.class);

    static {
        System.setProperty("atms_env_id", "test");
    }

    @Autowired
    private SqlSessionFactory sqlSessionFactory;
    @Autowired
    protected ObjectMapper objectMapper;

    @Autowired
    protected AreaMapper areaMapper;
    @Autowired
    protected AreaRegionMapper areaRegionMapper;
    @Autowired
    protected RegionMapper regionMapper;
    @Autowired
    protected EnterpriseAccountSetMapper enterpriseAccountSetMapper;
    @Autowired
    protected EnterpriseAccountMapper enterpriseAccountMapper;
    @Autowired
    protected StandardAccountMapper standardAccountMapper;
    @Autowired
    protected EnterpriseAccountSetOrgMapper enterpriseAccountSetOrgMapper;
    @Autowired
    protected AccountMappingMapper accountMappingMapper;
    @Autowired
    protected OperationLogBasicDataMapper operationLogBasicDataMapper;
    @Autowired
    protected OperationLogEnterPriseMapper operationLogEnterpriseMapper;
    @Autowired
    protected OrganizationMapper organizationMapper;
    @Autowired
    protected CustomerMapper customerMapper;
    @Autowired
    protected UserMapper userMapper;
    @Autowired
    protected MenuMapper menuMapper;
    @Autowired
    protected BusinessUnitMapper businessUnitMapper;
    @Autowired
    protected UserRoleMapper userRoleMapper;
    @Autowired
    protected RolePermissionMapper rolePermissionMapper;
    @Autowired
    protected PermissionMapper permissionMapper;
    @Autowired
    protected MailQueueMapper mailQueueMapper;
    @Autowired
    protected TemplateGroupMapper templateGroupMapper;
    @Autowired
    protected TemplateMapper templateMapper;
    @Autowired
    protected ServiceTypeMapper serviceTypeMapper;
    @Autowired
    protected ProjectClientMapper projectClientMapper;
    @Autowired
    protected RoleCategoryMapper roleCategoryMapper;
    @Autowired
    protected RoleMapper roleMapper;
    @Autowired
    protected UserDimensionValueMapper userDimensionValueMapper;
    @Autowired
    protected UserDimensionValueOrgMapper userDimensionValueOrgMapper;
    @Autowired
    protected UserDimensionValueRoleMapper userDimensionValueRoleMapper;
    @Autowired
    protected UserOrganizationMapper userOrganizationMapper;
    @Autowired
    protected UserOrganizationRoleMapper userOrganizationRoleMapper;
    @Autowired
    protected DimensionValueOrgMapper dimensionValueOrgMapper;
    @Autowired
    protected DimensionMapper dimensionMapper;
    @Autowired
    protected DimensionValueMapper dimensionValueMapper;
    @Autowired
    protected IndustryMapper industryMapper;
    @Autowired
    protected OrganizationStructureMapper organizationStructureMapper;
    @Autowired
    protected CacheMapper cacheMapper;
    @Autowired
    protected StatisticAttributeDimensionMapper statisticAttributeDimensionMapper;
    @Autowired
    protected StatisticAttributeMapper statisticAttributeMapper;
    @Autowired
    protected OperationLogOrganizationMapper operationLogOrganizationMapper;
    @Autowired
    protected OperationLogRoleMapper operationLogRoleMapper;
    @Autowired
    protected DictionaryMapper dictionaryMapper;
    @Autowired
    protected OperationLogUserMapper operationLogUserMapper;
    @Autowired
    protected OrganizationServiceTemplateGroupMapper organizationServiceTemplateGroupMapper;
    @Autowired
    protected DistributedIDService distributedIDService;
    @Autowired
    protected CellTemplateMapper cellTemplateMapper;
    @Autowired
    protected CellTemplateConfigMapper cellTemplateConfigMapper;
    @Autowired
    protected  TaxPayerReportRuleMapper taxPayerReportRuleMapper;
    @Autowired
    protected  TaxRuleSettingOrganizationMapper taxRuleSettingOrganizationMapper;
    @Autowired
    protected  TaxRuleSettingMapper taxRuleSettingMapper;
    @Autowired
    protected PeriodTemplateMapper periodTemplateMapper;

    protected void execSqlFile(String sqlFilePath) {

        Connection conn = null;
        ScriptRunner runner = null;
        Reader reader = null;
        try {
            conn = sqlSessionFactory.openSession().getConnection();
            runner = new ScriptRunner(conn);
            runner.setAutoCommit(true);
            runner.setFullLineDelimiter(true);
            runner.setDelimiter("GO");
            runner.setSendFullScript(false);
            // runner.setStopOnError(false);
            runner.setStopOnError(true);
            runner.setLogWriter(null);

            reader = new InputStreamReader(ClassLoader.getSystemResourceAsStream(sqlFilePath), "utf-8");
            runner.runScript(reader);

        } catch (Exception e) {
            logger.error("Error executing sql file " + sqlFilePath, e);
            throw Lang.wrapThrow(e);
        } finally {
            try {
                if (conn != null) {
                    runner.closeConnection();
                    conn.close();
                }
                if (reader != null) {
                    reader.close();
                }
            } catch (Exception e) {
                if (conn != null) {
                    conn = null;
                }
                if (reader != null) {
                    reader = null;
                }
            }
        }

    }

    protected void cleanUpAllTables() {
        cleanUpAreaTable();
        cleanUpAreaRegionTable();
        cleanUpRegionTable();
        cleanUpEnterpriseAccountSetTable();
        cleanUpEnterpriseAccountTable();
        cleanUpStandardAccountTable();
        cleanUpEnterpriseAccountSetOrgTable();
        accountMappingMapper.deleteByExample(null);
        cleanUpOperationLogBasicDataTable();
        cleanUpOperationLogEnterPriseTable();
        cleanUpOrganizationTable();
        userMapper.deleteByExample(null);
        cleanUpMenuTable();
        businessUnitMapper.deleteByExample(null);
        userRoleMapper.deleteByExample(null);
        rolePermissionMapper.deleteByExample(null);
        permissionMapper.deleteByExample(null);
        mailQueueMapper.deleteByExample(null);
        cleanUpTemplateGroupTable();
        cleanUpServiceTypeTable();
        cleanUpProjectClientTable();
        cleanUpIndustryTable();
        roleCategoryMapper.deleteByExample(null);
        roleMapper.deleteByExample(null);
        userDimensionValueMapper.deleteByExample(null);
        userDimensionValueOrgMapper.deleteByExample(null);
        userDimensionValueRoleMapper.deleteByExample(null);
        userOrganizationMapper.deleteByExample(null);
        userOrganizationRoleMapper.deleteByExample(null);
        dimensionValueOrgMapper.deleteByExample(null);
        organizationStructureMapper.deleteByExample(null);

        dimensionMapper.deleteByExample(null);
        dimensionValueMapper.deleteByExample(null);
        statisticAttributeMapper.deleteByExample(null);
        statisticAttributeDimensionMapper.deleteByExample(null);
        operationLogOrganizationMapper.deleteByExample(null);
        operationLogRoleMapper.deleteByExample(null);
        operationLogUserMapper.deleteByExample(null);
        organizationServiceTemplateGroupMapper.deleteByExample(null);
    }

    private void cleanUpProjectClientTable() {
        ProjectClientExample example = new ProjectClientExample();
        projectClientMapper.deleteByExample(example);
    }

    private void cleanUpIndustryTable() {
        IndustryExample example = new IndustryExample();
        industryMapper.deleteByExample(example);
    }

    private void cleanUpTemplateGroupTable() {
        TemplateGroupExample example = new TemplateGroupExample();
        templateGroupMapper.deleteByExample(example);
    }

    private void cleanUpServiceTypeTable() {
        ServiceTypeExample example = new ServiceTypeExample();
        serviceTypeMapper.deleteByExample(example);
    }

    protected void cleanUpAreaTable() {
        AreaExample example = new AreaExample();
        areaMapper.deleteByExample(example);
    }

    protected void cleanUpAreaRegionTable() {
        AreaRegionExample example = new AreaRegionExample();
        areaRegionMapper.deleteByExample(example);
    }

    protected void cleanUpRegionTable() {
        RegionExample example = new RegionExample();
        regionMapper.deleteByExample(example);
    }

    protected void cleanUpOperationLogBasicDataTable() {
        OperationLogBasicDataExample example = new OperationLogBasicDataExample();
        operationLogBasicDataMapper.deleteByExample(example);
    }

    protected void cleanUpOperationLogEnterPriseTable() {
        OperationLogEnterPriseExample example = new OperationLogEnterPriseExample();
        operationLogEnterpriseMapper.deleteByExample(example);
    }

    protected void cleanUpEnterpriseAccountSetTable() {
        EnterpriseAccountSetExample example = new EnterpriseAccountSetExample();
        enterpriseAccountSetMapper.deleteByExample(example);
    }

    protected void cleanUpEnterpriseAccountTable() {
        EnterpriseAccountExample example = new EnterpriseAccountExample();
        enterpriseAccountMapper.deleteByExample(example);
    }

    protected void cleanUpStandardAccountTable() {
        StandardAccountExample example = new StandardAccountExample();
        standardAccountMapper.deleteByExample(example);
    }

    protected void cleanUpEnterpriseAccountSetOrgTable() {
        EnterpriseAccountSetOrgExample example = new EnterpriseAccountSetOrgExample();
        enterpriseAccountSetOrgMapper.deleteByExample(example);
    }

    protected void cleanUpOrganizationTable() {
        OrganizationExample example = new OrganizationExample();
        organizationMapper.deleteByExample(example);
    }

    protected void cleanUpCustomerTable() {
        CustomerExample example = new CustomerExample();
        customerMapper.deleteByExample(example);
    }

    protected void cleanUpMenuTable() {
        MenuExample example = new MenuExample();
        menuMapper.deleteByExample(example);
    }
}