package com.kingdee.eas.custom.emp;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.apache.log4j.Logger;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import com.kingdee.bos.BOSException;

/**
 * 从 EAS_HOME/server/properties 加载同步 SQL，每次执行时重新读取配置文件。
 */
public class MultiDataToPersonBaseSqlLoader
{
    private static final Logger logger =
        Logger.getLogger("com.kingdee.eas.custom.emp.MultiDataToPersonBaseSqlLoader");

    public static final String CONFIG_RELATIVE_PATH =
        "/server/properties/baoye/emp/syncMultiDataToBase.xml";

    public static List<SqlTask> loadTasks() throws BOSException
    {
        String easHome = System.getProperty("EAS_HOME");
        if (easHome == null || easHome.trim().isEmpty()) {
            throw new BOSException("EAS_HOME 未配置，无法加载同步 SQL 配置");
        }

        File configFile = new File(easHome + CONFIG_RELATIVE_PATH);
        if (!configFile.exists()) {
            throw new BOSException("未找到同步 SQL 配置文件: " + configFile.getAbsolutePath());
        }

        File configDir = configFile.getParentFile();
        List<SqlTask> tasks = new ArrayList<SqlTask>();

        try {
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document document;
            FileInputStream inputStream = new FileInputStream(configFile);
            try {
                document = builder.parse(inputStream);
            } finally {
                inputStream.close();
            }

            Element root = document.getDocumentElement();
            String baseDirName = root.getAttribute("baseDir");
            File sqlBaseDir = baseDirName == null || baseDirName.trim().isEmpty()
                ? configDir
                : new File(configDir, baseDirName);

            NodeList taskNodes = root.getElementsByTagName("task");
            for (int i = 0; i < taskNodes.getLength(); i++) {
                Element taskElement = (Element) taskNodes.item(i);
                if (!isEnabled(taskElement)) {
                    continue;
                }

                SqlTask task = new SqlTask();
                task.setId(taskElement.getAttribute("id"));
                task.setDesc(taskElement.getAttribute("desc"));
                task.setDialect(parseDialect(taskElement.getAttribute("dialect")));
                task.setSql(readTaskSql(taskElement, sqlBaseDir));
                tasks.add(task);
            }
        } catch (Exception e) {
            logger.error("加载同步 SQL 配置失败: " + configFile.getAbsolutePath(), e);
            throw new BOSException(e);
        }

        if (tasks.isEmpty()) {
            throw new BOSException("同步 SQL 配置为空，请检查: " + configFile.getAbsolutePath());
        }

        logger.info("loaded sync sql tasks: " + tasks.size() + " from " + configFile.getAbsolutePath());
        return tasks;
    }

    private static boolean isEnabled(Element taskElement)
    {
        String enabled = taskElement.getAttribute("enabled");
        return enabled == null || enabled.trim().isEmpty() || "true".equalsIgnoreCase(enabled.trim());
    }

    private static boolean parseDialect(String dialect)
    {
        return dialect == null || dialect.trim().isEmpty() || "true".equalsIgnoreCase(dialect.trim());
    }

    private static String readTaskSql(Element taskElement, File sqlBaseDir) throws IOException, BOSException
    {
        String fileName = taskElement.getAttribute("file");
        if (fileName != null && !fileName.trim().isEmpty()) {
            File sqlFile = new File(sqlBaseDir, fileName.trim());
            if (!sqlFile.exists()) {
                throw new BOSException("SQL 文件不存在: " + sqlFile.getAbsolutePath());
            }
            byte[] bytes = Files.readAllBytes(sqlFile.toPath());
            return new String(bytes, StandardCharsets.UTF_8).trim();
        }

        String inlineSql = taskElement.getTextContent();
        if (inlineSql == null || inlineSql.trim().isEmpty()) {
            throw new BOSException("任务 [" + taskElement.getAttribute("id") + "] 未配置 file 或 SQL 内容");
        }
        return inlineSql.trim();
    }

    public static class SqlTask
    {
        private String id;
        private String desc;
        private boolean dialect;
        private String sql;

        public String getId()
        {
            return id;
        }

        public void setId(String id)
        {
            this.id = id;
        }

        public String getDesc()
        {
            return desc;
        }

        public void setDesc(String desc)
        {
            this.desc = desc;
        }

        public boolean isDialect()
        {
            return dialect;
        }

        public void setDialect(boolean dialect)
        {
            this.dialect = dialect;
        }

        public String getSql()
        {
            return sql;
        }

        public void setSql(String sql)
        {
            this.sql = sql;
        }
    }
}
