package xyz.wbsite.dbtool.javafx.manger.callable;

import xyz.wbsite.dbtool.javafx.manger.FreeMarkerManager;
import xyz.wbsite.dbtool.javafx.manger.ManagerFactory;
import xyz.wbsite.dbtool.javafx.manger.XmlManager;
import xyz.wbsite.dbtool.javafx.po.AbstractDBmapper;
import xyz.wbsite.dbtool.javafx.po.DataBase;
import xyz.wbsite.dbtool.javafx.po.Frame;
import xyz.wbsite.dbtool.javafx.po.Module;
import xyz.wbsite.dbtool.javafx.po.MySQLDBmapper;
import xyz.wbsite.dbtool.javafx.po.OracleDBmapper;
import xyz.wbsite.dbtool.javafx.po.Project;
import xyz.wbsite.dbtool.javafx.po.SQLiteDBmapper;
import xyz.wbsite.dbtool.javafx.po.Table;
import xyz.wbsite.dbtool.javafx.tool.Tool;
import xyz.wbsite.dbtool.web.frame.utils.FileUtil;
import xyz.wbsite.dbtool.web.frame.utils.ResourceUtil;

import java.io.File;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.concurrent.Callable;
import java.util.regex.Pattern;

public class SpringBootCallable implements Callable {

    private File root;
    private Project project;
    private AbstractDBmapper dBmapper;
    private FreeMarkerManager freeMarkerManager;

    public SpringBootCallable(Project project, File root) {
        this.root = root;
        this.project = project;
        this.freeMarkerManager = ManagerFactory.getFreeMarkerManager();
        // 根据配置获取数据库处理器
        if (project.getDatabase().name().equals(DataBase.MySQL.name())) {
            this.dBmapper = new MySQLDBmapper();
        } else if (project.getDatabase().name().equals(DataBase.Oracle.name())) {
            this.dBmapper = new OracleDBmapper();
        } else if (project.getDatabase().name().equals(DataBase.SQLite.name())) {
            this.dBmapper = new SQLiteDBmapper();
        } else {
            this.dBmapper = new MySQLDBmapper();
        }
    }

    public Boolean call() throws Exception {
        // 创建项目文件夹
        File dir = Tool.createPath(root, project.getName());
        // 清空内容
        Tool.clear(dir);

        // 生成java目录
        File javaDir = Tool.createPath(dir, "src", "main", "java");
        // 生成资源目录
        File resourcesDir = Tool.createPath(dir, "src", "main", "resources");
        // 生成域名目录
        File domainDir = javaDir;
        for (String s : project.getDomain().split("\\.")) {
            domainDir = Tool.createPath(domainDir, s);
        }
        // 生成单元测试java目录
        File testJavaDir = Tool.createPath(dir, "src", "test", "java");
        File testDomainDir = testJavaDir;
        for (String s : project.getDomain().split("\\.")) {
            testDomainDir = Tool.createPath(testDomainDir, s);
        }
        // 生成单元测试resources目录
        File testResourcesDir = Tool.createPath(dir, "src", "test", "resources");

        // 生成POM
        generatePom(dir, project);

        // Application
        System.out.println("生成模块:Application");
        generateApplication(Tool.createPath(domainDir), project);

        if (project.getFrame().value() > Frame.空白框架.value()) {//生成java文件
            //生成 Controller
            if (project.getFrame().value() >= Frame.接口框架.value()) {
                System.out.println("生成模块:action");
                generateController(Tool.createPath(domainDir, "action"), project);
            }

            // 生成 Config
            if (project.getFrame().value() >= Frame.服务框架.value()) {
                System.out.println("生成模块:config");
                generateConfig(Tool.createPath(domainDir, "config"), project);
            }

            // 模块
            generateModule(Tool.createPath(domainDir, "module"), project);

            if (project.getFrame().value() >= Frame.服务框架.value()) {
                generateModuleFor服务框架(Tool.createPath(domainDir, "module"), project);
            }

            if (project.getFrame().value() >= Frame.接口框架.value()) {
                generateModuleFor接口框架(Tool.createPath(domainDir, "module"), project);
            }

            if (project.getFrame().value() >= Frame.网页框架.value()) {
                generateModuleFor网页框架(Tool.createPath(domainDir, "module"), project);
            }

            // frame等内容
            if (project.getFrame().value() > Frame.空白框架.value()) {
                System.out.println("生成模块:frame");
                generateFrame(Tool.createPath(domainDir, "frame"), project);
            }

            // Task
            System.out.println("生成模块:task");
            if (project.getFrame().value() > Frame.空白框架.value()) {
                generateTask(Tool.createPath(domainDir, "task"), project);
            }
        }

        //生成resources文件
        generateResources(resourcesDir, project);

        if (project.getFrame().value() > Frame.空白框架.value()) {
            {//生成Test
                System.out.println("生成模块:Test");
                generateTest(testDomainDir, project);
            }

            {//生成Test Resources
                System.out.println("生成模块:Test Resources");
                generateTestResources(testResourcesDir, project);
            }
        }

        System.out.println("finish");
        return true;
    }


    /**
     * 生成POM.xml
     *
     * @param root
     * @param project
     */
    public void generatePom(File root, Project project) {
        HashMap<String, Object> ctx = new HashMap<String, Object>();
        ctx.put("projectName", project.getName());
        ctx.put("domain", project.getDomain());
        ctx.put("dataBase", project.getDatabase().toString());
        ctx.put("project", project);
        freeMarkerManager.outputTemp(Tool.createFile(root, "pom.xml"), "SpringBoot/pom.ftl", ctx);
    }

    /**
     * 生成Controller类
     *
     * @param root
     * @param project
     */
    public void generateController(File root, Project project) {
        Tool.clear(root);
        HashMap<String, Object> ctx = new HashMap<String, Object>();
        ctx.put("project", project);
        ctx.put("domain", project.getDomain());
        ctx.put("author", project.getAuthor());
        ctx.put("modules", project.getModules());

        if (project.getFrame().value() >= Frame.网页框架.value()) {
            File control = Tool.createPath(root, "control");
            freeMarkerManager.outputTemp(Tool.createFile(control, "Header.java"), "SpringBoot/java/action/control/Header.java", ctx);

            File screen = Tool.createPath(root, "screen");
            freeMarkerManager.outputTemp(Tool.createFile(screen, "Index.java"), "SpringBoot/java/action/screen/Index.java", ctx);

            {// ajax 属于web内容
                File ajax = Tool.createPath(root, "ajax");
                HashMap<String, Object> ctxss = new HashMap<String, Object>();
                ctxss.put("domain", project.getDomain());
                ctxss.put("author", project.getAuthor());

                for (Module module : project.getModules()) {
                    File m = Tool.createPath(ajax, module.getModuleName());
                    ctxss.put("moduleName", module.getModuleName());

                    for (Table table : module.getTables()) {
                        if (table.getAjax()) {
                            ctxss.put("table", table);
                            freeMarkerManager.outputTemp(Tool.createFile(m, table.getCName() + "Ajax.java"), "SpringBoot/java/action/ajax/Ajax.java", ctxss);
                        }
                    }
                }

                if (project.getFrame().value() >= Frame.网页框架.value()) {//生成系统模块
                    File wsys = Tool.createPath(ajax, "wsys");
                    for (String name : ResourceUtil.getResourceFiles("/modules/SpringBoot/java/action/ajax/wsys/")) {
                        freeMarkerManager.outputTemp(Tool.createFile(wsys, name), "SpringBoot/java/action/ajax/wsys/" + name, ctx);
                    }

                    File wmnt = Tool.createPath(ajax, "wmnt");
                    for (String name : ResourceUtil.getResourceFiles("/modules/SpringBoot/java/action/ajax/wmnt/")) {
                        freeMarkerManager.outputTemp(Tool.createFile(wsys, name), "SpringBoot/java/action/ajax/wmnt/" + name, ctx);
                    }
                }
            }
        }

        if (project.isNeedApi()) {
            File api = Tool.createPath(root, "api");

            for (Module module : project.getModules()) {
                File m = Tool.createPath(api, module.getModuleName());

                for (Table table : module.getTables()) {
                    if (table.getApi()) {
                        HashMap<String, Object> ctxss = new HashMap<String, Object>();
                        ctxss.put("domain", project.getDomain());
                        ctxss.put("module", module.getModuleName());
                        ctxss.put("author", project.getAuthor());
                        ctxss.put("table", table);
                        freeMarkerManager.outputTemp(Tool.createFile(m, table.getCName() + "Api.java"), "SpringBoot/java/action/api/Api.java", ctxss);
                    }
                }
            }

            if (project.getFrame().value() >= Frame.网页框架.value()) {//生成系统模块
                File wsys = Tool.createPath(api, "wsys");

                for (String name : ResourceUtil.getResourceFiles("/modules/SpringBoot/java/action/api/wsys/")) {
                    freeMarkerManager.outputTemp(Tool.createFile(wsys, name), "SpringBoot/java/action/api/wsys/" + name, ctx);
                }
            }
        }

        freeMarkerManager.outputTemp(Tool.createFile(root, "GlobalController.java"), "SpringBoot/java/action/GlobalController.java", ctx);
    }

    public void generateConfig(File root, Project project) {
        if (!root.exists()) {
            root.mkdirs();
        } else {
            Tool.clear(root);
        }
        HashMap<String, Object> ctx = new HashMap<String, Object>();
        ctx.put("project", project);
        ctx.put("domain", project.getDomain());
        ctx.put("projectName", project.getName());
        ctx.put("author", project.getAuthor());

        //config
        if (project.getFrame().value() >= Frame.网页框架.value()) {
            freeMarkerManager.outputTemp(Tool.createFile(root, "FreeMarkerConfig.java"), "SpringBoot/java/config/FreeMarkerConfig.java", ctx);
            freeMarkerManager.outputTemp(Tool.createFile(root, "WebMvcConfig.java"), "SpringBoot/java/config/WebMvcConfig.java", ctx);
            freeMarkerManager.outputTemp(Tool.createFile(root, "CacheConfig.java"), "SpringBoot/java/config/CacheConfig.java", ctx);
            freeMarkerManager.outputTemp(Tool.createFile(root, "SecurityConfig.java"), "SpringBoot/java/config/SecurityConfig.java", ctx);
        }
        if (project.getFrame().value() >= Frame.接口框架.value()) {
            freeMarkerManager.outputTemp(Tool.createFile(root, "ActionConfig.java"), "SpringBoot/java/config/ActionConfig.java", ctx);
        }
        if (project.getFrame().value() >= Frame.服务框架.value()) {
            freeMarkerManager.outputTemp(Tool.createFile(root, "TaskConfig.java"), "SpringBoot/java/config/TaskConfig.java", ctx);
        }
        if (project.isNeedAsync()) {
            freeMarkerManager.outputTemp(Tool.createFile(root, "ThreadPoolConfig.java"), "SpringBoot/java/config/ThreadPoolConfig.java", ctx);
        }
        if (project.getDatabase().name().equals(DataBase.SQLite.name())) {
            freeMarkerManager.outputTemp(Tool.createFile(root, "SQLiteConfig.java"), "SpringBoot/java/config/SQLiteConfig.java", ctx);
        }
        if (project.isNeedMoreDB()) {
            freeMarkerManager.outputTemp(Tool.createFile(root, "MapperMainConfig.java"), "SpringBoot/java/config/MapperMainConfig.java", ctx);
            freeMarkerManager.outputTemp(Tool.createFile(root, "MapperTwoConfig.java"), "SpringBoot/java/config/MapperTwoConfig.java", ctx);
        }
    }

    public void generateModule(File root, Project project) {
        if (!root.exists()) {
            root.mkdirs();
        } else {
            Tool.clear(root);
        }

        HashMap<String, Object> ctx = new HashMap<String, Object>();
        for (Module module : project.getModules()) {// 业务模块
            ctx.put("project", project);
            ctx.put("module", module);
            ctx.put("domain", project.getDomain());
            ctx.put("author", project.getAuthor());
            ctx.put("moduleName", module.getModuleName());
            ctx.put("dataBase", project.getDatabase().toString());

            File ent = Tool.createPath(Tool.createPath(root, module.getModuleName()), "ent");
            File mpr = Tool.createPath(Tool.createPath(root, module.getModuleName()), "mpr");
            File mgr = Tool.createPath(Tool.createPath(root, module.getModuleName()), "mgr");
            File req = Tool.createPath(Tool.createPath(root, module.getModuleName()), "req");
            File rsp = Tool.createPath(Tool.createPath(root, module.getModuleName()), "rsp");

            if (module.getNeedGenerate()) {
                module.setProjectAuthor(project.getAuthor());
                module.setProjectBasePackage(project.getDomain());
                module.setProjectName(project.getName());

                for (Table table : module.getTables()) {
                    ctx.put("table", table);

                    // 生成Ent
                    File file = Tool.createFile(ent, Tool.ABB2Abb(table.getTableName()) + ".java");
                    freeMarkerManager.outputTemp(file, "SpringBoot/java/module/ent/entity.ftl", ctx);

                    // 生成Mapper
                    if (table.getSys()) {
                        freeMarkerManager.outputTemp(Tool.createFile(mpr, Tool.ABB2Abb(table.getTableName()) + "Mapper" + ".java"), "SpringBoot/java/module/mpr/Mapper.java", ctx);
                        freeMarkerManager.outputTemp(Tool.createFile(mpr, Tool.ABB2Abb(table.getTableName()) + "Mapper" + ".xml"), "SpringBoot/java/module/mpr/" + project.getDatabase().name() + "_mapper.xml", ctx);
                    } else {
                        freeMarkerManager.outputTemp(Tool.createFile(mpr, Tool.ABB2Abb(table.getTableName()) + "Mapper" + ".java"), "SpringBoot/java/module/mpr/Mapper_NSYS.java", ctx);
                        freeMarkerManager.outputTemp(Tool.createFile(mpr, Tool.ABB2Abb(table.getTableName()) + "Mapper" + ".xml"), "SpringBoot/java/module/mpr/" + project.getDatabase().name() + "_NSYS_mapper.xml", ctx);
                    }

                    freeMarkerManager.outputTemp(Tool.createFile(mgr, Tool.ABB2Abb(table.getTableName()) + "Manager" + ".java"), "SpringBoot/java/module/mgr/manager.ftl", ctx);
                    freeMarkerManager.outputTemp(Tool.createFile(mgr, Tool.ABB2Abb(table.getTableName()) + "ManagerImpl" + ".java"), "SpringBoot/java/module/mgr/managerImpl.ftl", ctx);

                    if (table.getCreate()) {
                        freeMarkerManager.outputTemp(Tool.createFile(req, Tool.ABB2Abb(table.getTableName()) + "CreateRequest" + ".java"), "SpringBoot/java/module/req/createRequestClass.ftl", ctx);
                        freeMarkerManager.outputTemp(Tool.createFile(rsp, Tool.ABB2Abb(table.getTableName()) + "CreateResponse" + ".java"), "SpringBoot/java/module/rsp/createResponseClass.ftl", ctx);
                    }

                    if (table.getDelete()) {
                        freeMarkerManager.outputTemp(Tool.createFile(req, Tool.ABB2Abb(table.getTableName()) + "DeleteRequest" + ".java"), "SpringBoot/java/module/req/deleteRequestClass.ftl", ctx);
                        freeMarkerManager.outputTemp(Tool.createFile(rsp, Tool.ABB2Abb(table.getTableName()) + "DeleteResponse" + ".java"), "SpringBoot/java/module/rsp/deleteResponseClass.ftl", ctx);
                    }

                    if (table.getUpdate()) {
                        freeMarkerManager.outputTemp(Tool.createFile(req, Tool.ABB2Abb(table.getTableName()) + "UpdateRequest" + ".java"), "SpringBoot/java/module/req/updateRequestClass.ftl", ctx);
                        freeMarkerManager.outputTemp(Tool.createFile(rsp, Tool.ABB2Abb(table.getTableName()) + "UpdateResponse" + ".java"), "SpringBoot/java/module/rsp/updateResponseClass.ftl", ctx);
                    }

                    if (table.getFind()) {
                        freeMarkerManager.outputTemp(Tool.createFile(req, Tool.ABB2Abb(table.getTableName()) + "FindRequest" + ".java"), "SpringBoot/java/module/req/findRequestClass.ftl", ctx);
                        freeMarkerManager.outputTemp(Tool.createFile(rsp, Tool.ABB2Abb(table.getTableName()) + "FindResponse" + ".java"), "SpringBoot/java/module/rsp/findResponseClass.ftl", ctx);
                    }

                    if (table.getGet()) {
                        freeMarkerManager.outputTemp(Tool.createFile(req, Tool.ABB2Abb(table.getTableName()) + "GetRequest" + ".java"), "SpringBoot/java/module/req/getRequestClass.ftl", ctx);
                        freeMarkerManager.outputTemp(Tool.createFile(rsp, Tool.ABB2Abb(table.getTableName()) + "GetResponse" + ".java"), "SpringBoot/java/module/rsp/getResponseClass.ftl", ctx);
                    }

                    if (table.getSearch()) {
                        freeMarkerManager.outputTemp(Tool.createFile(req, Tool.ABB2Abb(table.getTableName()) + "SearchRequest" + ".java"), "SpringBoot/java/module/req/searchRequestClass.ftl", ctx);
                        freeMarkerManager.outputTemp(Tool.createFile(rsp, Tool.ABB2Abb(table.getTableName()) + "SearchResponse" + ".java"), "SpringBoot/java/module/rsp/searchResponseClass.ftl", ctx);
                    }
                }
            }
        }
    }

    public void generateModuleFor服务框架(File root, Project project) {
        HashMap<String, Object> ctx = new HashMap<String, Object>();
        ctx.put("project", project);
        ctx.put("domain", project.getDomain());
        ctx.put("author", project.getAuthor());
        ctx.put("dataBase", project.getDatabase().toString());
        File ent = Tool.createPath(root, "wsvr", "ent");
        File mpr = Tool.createPath(root, "wsvr", "mpr");
        File mgr = Tool.createPath(root, "wsvr", "mgr");
        File req = Tool.createPath(root, "wsvr", "req");
        File rsp = Tool.createPath(root, "wsvr", "rsp");
        for (String name : ResourceUtil.getResourceFiles("/modules/SpringBoot/java/module/wsvr/ent/")) {
            freeMarkerManager.outputTemp(Tool.createFile(ent, name), "SpringBoot/java/module/wsvr/ent/" + name, ctx);
        }
        for (String name : ResourceUtil.getResourceFiles("/modules/SpringBoot/java/module/wsvr/mgr/")) {
            freeMarkerManager.outputTemp(Tool.createFile(mgr, name), "SpringBoot/java/module/wsvr/mgr/" + name, ctx);
        }
        for (String name : ResourceUtil.getResourceFiles("/modules/SpringBoot/java/module/wsvr/mpr/")) {
            if (name.endsWith(".java")) {
                freeMarkerManager.outputTemp(Tool.createFile(mpr, name), "SpringBoot/java/module/wsvr/mpr/" + name, ctx);
            } else if (name.contains(project.getDatabase().name())) {
                freeMarkerManager.outputTemp(Tool.createFile(mpr, name.replaceAll(project.getDatabase().name() + "_", "")), "SpringBoot/java/module/wsvr/mpr/" + name, ctx);
            }
        }
        for (String name : ResourceUtil.getResourceFiles("/modules/SpringBoot/java/module/wsvr/req/")) {
            freeMarkerManager.outputTemp(Tool.createFile(req, name), "SpringBoot/java/module/wsvr/req/" + name, ctx);
        }
        for (String name : ResourceUtil.getResourceFiles("/modules/SpringBoot/java/module/wsvr/rsp/")) {
            freeMarkerManager.outputTemp(Tool.createFile(rsp, name), "SpringBoot/java/module/wsvr/rsp/" + name, ctx);
        }
    }

    public void generateModuleFor接口框架(File root, Project project) {
        HashMap<String, Object> ctx = new HashMap<String, Object>();
        ctx.put("project", project);
        ctx.put("domain", project.getDomain());
        ctx.put("author", project.getAuthor());
        ctx.put("dataBase", project.getDatabase().toString());
        File ent = Tool.createPath(root, "wsys", "ent");
        File mpr = Tool.createPath(root, "wsys", "mpr");
        File mgr = Tool.createPath(root, "wsys", "mgr");
        File req = Tool.createPath(root, "wsys", "req");
        File rsp = Tool.createPath(root, "wsys", "rsp");
        Pattern compile = Pattern.compile("Dict.*");
        for (String name : ResourceUtil.getResourceFiles("/modules/SpringBoot/java/module/wsys/ent/")) {
            if (compile.matcher(name).find()) {
                freeMarkerManager.outputTemp(Tool.createFile(ent, name), "SpringBoot/java/module/wsys/ent/" + name, ctx);
            }
        }
        for (String name : ResourceUtil.getResourceFiles("/modules/SpringBoot/java/module/wsys/mgr/")) {
            if (compile.matcher(name).find()) {
                freeMarkerManager.outputTemp(Tool.createFile(mgr, name), "SpringBoot/java/module/wsys/mgr/" + name, ctx);
            }
        }
        for (String name : ResourceUtil.getResourceFiles("/modules/SpringBoot/java/module/wsys/mpr/")) {
            if (compile.matcher(name).find()) {
                if (name.endsWith(".java")) {
                    freeMarkerManager.outputTemp(Tool.createFile(mpr, name), "SpringBoot/java/module/wsys/mpr/" + name, ctx);
                } else if (name.contains(project.getDatabase().name())) {
                    freeMarkerManager.outputTemp(Tool.createFile(mpr, name.replaceAll(project.getDatabase().name() + "_", "")), "SpringBoot/java/module/wsys/mpr/" + name, ctx);
                }
            }
        }
        for (String name : ResourceUtil.getResourceFiles("/modules/SpringBoot/java/module/wsys/req/")) {
            if (compile.matcher(name).find()) {
                freeMarkerManager.outputTemp(Tool.createFile(req, name), "SpringBoot/java/module/wsys/req/" + name, ctx);
            }
        }
        for (String name : ResourceUtil.getResourceFiles("/modules/SpringBoot/java/module/wsys/rsp/")) {
            if (compile.matcher(name).find()) {
                freeMarkerManager.outputTemp(Tool.createFile(rsp, name), "SpringBoot/java/module/wsys/rsp/" + name, ctx);
            }
        }
    }

    public void generateModuleFor网页框架(File root, Project project) {
        HashMap<String, Object> ctx = new HashMap<String, Object>();
        ctx.put("project", project);
        ctx.put("domain", project.getDomain());
        ctx.put("moduleName", "wsys");
        ctx.put("author", project.getAuthor());
        ctx.put("dataBase", project.getDatabase().toString());

        File ent = Tool.createPath(root, "wsys", "ent");
        File mpr = Tool.createPath(root, "wsys", "mpr");
        File mgr = Tool.createPath(root, "wsys", "mgr");
        File req = Tool.createPath(root, "wsys", "req");
        File rsp = Tool.createPath(root, "wsys", "rsp");
        for (String name : ResourceUtil.getResourceFiles("/modules/SpringBoot/java/module/wsys/ent/")) {
            freeMarkerManager.outputTemp(Tool.createFile(ent, name), "SpringBoot/java/module/wsys/ent/" + name, ctx);
        }

        for (String name : ResourceUtil.getResourceFiles("/modules/SpringBoot/java/module/wsys/mgr/")) {
            if (name.contains("TokensManager") && project.getFrame().value() < Frame.接口框架.value()) {// 当不需要Web和Api时不需要处理Token问题
                continue;
            }
            freeMarkerManager.outputTemp(Tool.createFile(mgr, name), "SpringBoot/java/module/wsys/mgr/" + name, ctx);
        }

        for (String name : ResourceUtil.getResourceFiles("/modules/SpringBoot/java/module/wsys/mpr/")) {
            if (name.endsWith(".java")) {
                freeMarkerManager.outputTemp(Tool.createFile(mpr, name), "SpringBoot/java/module/wsys/mpr/" + name, ctx);
            } else if (name.contains(project.getDatabase().name())) {
                freeMarkerManager.outputTemp(Tool.createFile(mpr, name.replaceAll(project.getDatabase().name() + "_", "")), "SpringBoot/java/module/wsys/mpr/" + name, ctx);
            }
        }

        for (String name : ResourceUtil.getResourceFiles("/modules/SpringBoot/java/module/wsys/req/")) {
            freeMarkerManager.outputTemp(Tool.createFile(req, name), "SpringBoot/java/module/wsys/req/" + name, ctx);
        }

        for (String name : ResourceUtil.getResourceFiles("/modules/SpringBoot/java/module/wsys/rsp/")) {
            freeMarkerManager.outputTemp(Tool.createFile(rsp, name), "SpringBoot/java/module/wsys/rsp/" + name, ctx);
        }
    }


    /**
     * 生成frame类
     *
     * @param root
     * @param project
     */
    public void generateFrame(File root, Project project) {
        if (!root.exists()) {
            root.mkdirs();
        } else {
            Tool.clear(root);
        }
        HashMap<String, Object> ctx = new HashMap<String, Object>();
        ctx.put("project", project);
        ctx.put("domain", project.getDomain());
        ctx.put("moduleName", project.getName());
        ctx.put("timestamp", new Date().getTime());

        //auth
        File auth = Tool.createPath(root, "auth");
        for (String name : ResourceUtil.getResourceFiles("/modules/SpringBoot/java/frame/auth/")) {
            freeMarkerManager.outputTemp(Tool.createFile(auth, name), "SpringBoot/java/frame/auth/" + name, ctx);
        }

        //base
        File base = Tool.createPath(root, "base");
        for (String name : ResourceUtil.getResourceFiles("/modules/SpringBoot/java/frame/base/")) {
            freeMarkerManager.outputTemp(Tool.createFile(base, name), "SpringBoot/java/frame/base/" + name, ctx);
        }

        //utils
        File utils = Tool.createPath(root, "utils");
        for (String name : ResourceUtil.getResourceFiles("/modules/SpringBoot/java/frame/utils/")) {
            ArrayList<String> filters = new ArrayList<>();
            filters.add("MailUtil.java");

            if (filters.contains(name)) {
                if (project.isNeedEMail()) {
                    freeMarkerManager.outputTemp(Tool.createFile(utils, name), "SpringBoot/java/frame/utils/" + name, ctx);
                }
            } else {
                freeMarkerManager.outputTemp(Tool.createFile(utils, name), "SpringBoot/java/frame/utils/" + name, ctx);
            }
        }

        File schedule = Tool.createPath(root, "schedule");
        //schedule
        for (String name : ResourceUtil.getResourceFiles("/modules/SpringBoot/java/frame/schedule/")) {
            freeMarkerManager.outputTemp(Tool.createFile(schedule, name), "SpringBoot/java/frame/schedule/" + name, ctx);
        }

        //excel
        if (project.getFrame().value() >= Frame.网页框架.value()) {
            File excel = Tool.createPath(root, "excel");
            File excelannotation = Tool.createPath(excel, "annotation");
            File excelconverter = Tool.createPath(excel, "converter");
            File exception = Tool.createPath(excel, "exception");
            File excelhandler = Tool.createPath(excel, "handler");
            File excellistener = Tool.createPath(excel, "listener");
            for (String name : ResourceUtil.getResourceFiles("/modules/SpringBoot/java/frame/excel/")) {
                freeMarkerManager.outputTemp(Tool.createFile(excel, name), "SpringBoot/java/frame/excel/" + name, ctx);
            }
            for (String name : ResourceUtil.getResourceFiles("/modules/SpringBoot/java/frame/excel/annotation/")) {
                freeMarkerManager.outputTemp(Tool.createFile(excelannotation, name), "SpringBoot/java/frame/excel/annotation/" + name, ctx);
            }
            for (String name : ResourceUtil.getResourceFiles("/modules/SpringBoot/java/frame/excel/converter/")) {
                freeMarkerManager.outputTemp(Tool.createFile(excelconverter, name), "SpringBoot/java/frame/excel/converter/" + name, ctx);
            }
            for (String name : ResourceUtil.getResourceFiles("/modules/SpringBoot/java/frame/excel/exception/")) {
                freeMarkerManager.outputTemp(Tool.createFile(exception, name), "SpringBoot/java/frame/excel/exception/" + name, ctx);
            }
            for (String name : ResourceUtil.getResourceFiles("/modules/SpringBoot/java/frame/excel/handler/")) {
                freeMarkerManager.outputTemp(Tool.createFile(excelhandler, name), "SpringBoot/java/frame/excel/handler/" + name, ctx);
            }
            for (String name : ResourceUtil.getResourceFiles("/modules/SpringBoot/java/frame/excel/listener/")) {
                freeMarkerManager.outputTemp(Tool.createFile(excellistener, name), "SpringBoot/java/frame/excel/listener/" + name, ctx);
            }
        }

        //validation
        if (project.getFrame().value() >= Frame.接口框架.value()) {
            File validation = Tool.createPath(root, "validation");
            for (String name : ResourceUtil.getResourceFiles("/modules/SpringBoot/java/frame/validation/")) {
                freeMarkerManager.outputTemp(Tool.createFile(validation, name), "SpringBoot/java/frame/validation/" + name, ctx);
            }
        }
    }

    /**
     * 生成frame类
     *
     * @param root
     * @param project
     */
    public void generateTask(File root, Project project) {
        if (!root.exists()) {
            root.mkdirs();
        } else {
            Tool.clear(root);
        }
        HashMap<String, Object> ctx = new HashMap<String, Object>();
        ctx.put("domain", project.getDomain());
        ctx.put("moduleName", project.getName());

        //task
        for (String name : ResourceUtil.getResourceFiles("/modules/SpringBoot/java/task/")) {
            if (name.contains("TokenTask") && project.getFrame().value() < Frame.网页框架.value()) {
                continue;
            }
            freeMarkerManager.outputTemp(Tool.createFile(root, name), "SpringBoot/java/task/" + name, ctx);
        }
    }

    /**
     * 生成base类
     *
     * @param root
     * @param project
     */
    public void generateApplication(File root, Project project) {
        HashMap<String, Object> ctx = new HashMap<String, Object>();
        ctx.put("domain", project.getDomain());
        ctx.put("project", project);
        freeMarkerManager.outputTemp(Tool.createFile(root, "Application.java"), "SpringBoot/java/Application.ftl", ctx);
    }

    /**
     * 生成Resources
     *
     * @param root
     * @param project
     */
    public void generateResources(File root, Project project) {
        HashMap<String, Object> ctx = new HashMap<String, Object>();
        ctx.put("domain", project.getDomain());
        ctx.put("dataBase", project.getDatabase().toString());
        ctx.put("author", project.getAuthor());
        ctx.put("dBmapper", dBmapper);
        ctx.put("author", project.getAuthor());
        ctx.put("projectName", project.getName());
        ctx.put("project", project);

        freeMarkerManager.outputTemp(Tool.createFile(root, "application.properties"), "SpringBoot/resources/application.ftl", ctx);

        if (project.getFrame().value() > Frame.空白框架.value()) {
            freeMarkerManager.outputTemp(Tool.createFile(root, "start-dev.bat"), "SpringBoot/resources/start-dev.bat", ctx);
            freeMarkerManager.outputTemp(Tool.createFile(root, "start-prod.bat"), "SpringBoot/resources/start-prod.bat", ctx);
            freeMarkerManager.outputTemp(Tool.createFile(root, "application-dev.properties"), "SpringBoot/resources/application-dev.ftl", ctx);
            freeMarkerManager.outputTemp(Tool.createFile(root, "application-prod.properties"), "SpringBoot/resources/application-prod.ftl", ctx);
            Tool.outputResource("SpringBoot/resources/logback-spring-dev.xml", Tool.createFile(root, "logback-spring-dev.xml"));
            Tool.outputResource("SpringBoot/resources/logback-spring-prod.xml", Tool.createFile(root, "logback-spring-prod.xml"));


            File dbtool = Tool.createPath(root, "dbtool");
            {
                XmlManager xmlManager = ManagerFactory.getXmlManager();
                xmlManager.saveAs(dbtool, project);
            }

            for (Module module : project.getModules()) {
                ctx.put("moduleName", module.getModuleName());
                ctx.put("module", module);
                File tableDir = Tool.createPath(dbtool, module.getModuleName() + "_table");
                for (Table table : module.getTables()) {
                    ctx.put("table", table);
                    freeMarkerManager.outputTemp(Tool.createFile(tableDir, project.getDatabase().name() + "_" + table.getTableName() + ".sql"), "SpringBoot/resources/dbtool/table.ftl", ctx);
                }
                freeMarkerManager.outputTemp(Tool.createFile(tableDir, project.getDatabase().name() + "_ALL_TABLE" + ".sql"), "SpringBoot/resources/dbtool/tableAll.ftl", ctx);
            }

            if (project.getFrame().value() >= Frame.服务框架.value()) {
                File wsvr = Tool.createPath(dbtool, "wsvr_table");

                for (String name : ResourceUtil.getResourceFiles("/modules/SpringBoot/resources/dbtool/wsvr/")) {
                    if (name.contains(project.getDatabase().name())) {
                        freeMarkerManager.outputTemp(Tool.createFile(wsvr, name), "SpringBoot/resources/dbtool/wsvr/" + name, ctx);
                    }
                }
            }

            if (project.getFrame().value() >= Frame.网页框架.value()) {//生成系统模块
                File wsys = Tool.createPath(dbtool, "wsys_table");

                for (String name : ResourceUtil.getResourceFiles("/modules/SpringBoot/resources/dbtool/wsys/")) {
                    if (name.contains(project.getDatabase().name())) {
                        freeMarkerManager.outputTemp(Tool.createFile(wsys, name), "SpringBoot/resources/dbtool/wsys/" + name, ctx);
                    }
                }
            }

//        if (DataBase.Oracle.name().equals(project.getDatabase().name())) {
//            File lib = Tool.createPath(root, "lib");
//            Tool.outputResource("SpringBoot/resources/lib/ojdbc7-12.1.0.2.jar", Tool.createFile(lib, "ojdbc7-12.1.0.2.jar"));
//        }

            if (DataBase.SQLite.name().equals(project.getDatabase().name())) {
                File dbFile = Tool.createFile(root, project.getName() + ".db3");
                Connection connection = null;
                Statement statement = null;
                try {
                    Class.forName("org.sqlite.JDBC");
                    connection = DriverManager.getConnection("jdbc:sqlite:" + dbFile);

                    for (File fileModule : dbtool.listFiles()) {
                        if (!fileModule.isDirectory()) {
                            continue;
                        }
                        for (File file : fileModule.listFiles()) {
                            if (file.getName().startsWith("SQLite_") && !file.getName().startsWith("SQLite_ALL_") && file.getName().endsWith(".sql")) {
                                statement = connection.createStatement();
                                String sql = FileUtil.readFileToString(file);
                                statement.execute(sql);
                                statement.close();
                            }
                        }
                    }
                } catch (ClassNotFoundException | SQLException | IOException e) {
                    e.printStackTrace();
                } finally {
                    try {
                        if (statement != null) statement.close();
                        if (connection != null) connection.close();
                    } catch (Exception e) {

                    }
                }
            }

            if (project.getFrame().value() >= Frame.网页框架.value()) {
                System.out.println("生成模块:Static");
                File static_ = Tool.createPath(root, "static");
                File css = Tool.createPath(static_, "css");
                File img = Tool.createPath(static_, "img");
                File dist = Tool.createPath(static_, "dist");
                Tool.outputResource("SpringBoot/resources/static/favicon.ico", Tool.createFile(static_, "favicon.ico"));

                //css文件
                freeMarkerManager.outputTemp(Tool.createFile(css, "base.css"), "SpringBoot/resources/static/css/base.css", ctx);

                //img
                Tool.outputResource("SpringBoot/resources/static/img/logo.png", Tool.createFile(img, "logo.png"));

                // dist文件jquery + vue + vue-router + axios
                Tool.outputResource("SpringBoot/resources/static/dist/lib.min.js", Tool.createFile(dist, "lib.min.js"));

                //element-ui
                Tool.outputResource("SpringBoot/resources/static/dist/index.min.js", Tool.createFile(dist, "index.min.js"));
                Tool.outputResource("SpringBoot/resources/static/dist/index.min.css", Tool.createFile(dist, "index.min.css"));

                File fonts = Tool.createPath(dist, "fonts");
                Tool.outputResource("SpringBoot/resources/static/dist/fonts/w-e-icon.woff", Tool.createFile(fonts, "w-e-icon.woff"));
                Tool.outputResource("SpringBoot/resources/static/dist/fonts/element-icons.woff", Tool.createFile(fonts, "element-icons.woff"));
                Tool.outputResource("SpringBoot/resources/static/dist/fonts/element-icons.ttf", Tool.createFile(fonts, "element-icons.ttf"));

                System.out.println("生成模块:Templates");
                File templates = Tool.createPath(root, "templates");
                File control = Tool.createPath(templates, "control");
                File layout = Tool.createPath(templates, "layout");
                File screen = Tool.createPath(templates, "screen");
                Tool.outputResource("SpringBoot/resources/templates/control/nav.ftl", Tool.createFile(control, "nav.ftl"));
                Tool.outputResource("SpringBoot/resources/templates/control/macro.ftl", Tool.createFile(control, "macro.ftl"));
                Tool.outputResource("SpringBoot/resources/templates/layout/default.ftl", Tool.createFile(layout, "default.ftl"));
                Tool.outputResource("SpringBoot/resources/templates/screen/home.ftl", Tool.createFile(screen, "home.ftl"));
                Tool.outputResource("SpringBoot/resources/templates/screen/login.ftl", Tool.createFile(screen, "login.ftl"));
                Tool.outputResource("SpringBoot/resources/templates/403.ftl", Tool.createFile(templates, "403.ftl"));
                Tool.outputResource("SpringBoot/resources/templates/404.ftl", Tool.createFile(templates, "404.ftl"));
                Tool.outputResource("SpringBoot/resources/templates/500.ftl", Tool.createFile(templates, "500.ftl"));

                freeMarkerManager.outputTemp(Tool.createFile(screen, "index.ftl"), "SpringBoot/resources/templates/screen/index.ftl", ctx);

                for (Module mo : project.getModules()) {
                    for (Table table : mo.getTables()) {
                        if (table.getHtml()) {
                            File module = Tool.createPath(screen, mo.getModuleName());
                            ctx.put("table", table);
                            ctx.put("module", module);
                            ctx.put("fields", table.getFields());
                            File file = Tool.createFile(module, table.getFName() + ".ftl");
                            freeMarkerManager.outputTemp(file, "SpringBoot/resources/templates/screen/module/mgr.ftl", ctx);
                        }
                    }
                }

                //生成网页
                if (project.getFrame().value() >= Frame.网页框架.value()) {
                    File wsys = Tool.createPath(screen, "wsys");
                    for (String name : ResourceUtil.getResourceFiles("/modules/SpringBoot/resources/templates/screen/module/wsys/")) {
                        Tool.outputResource("SpringBoot/resources/templates/screen/module/wsys/" + name, Tool.createFile(wsys, name));
                    }
                    File wmnt = Tool.createPath(screen, "wmnt");
                    for (String name : ResourceUtil.getResourceFiles("/modules/SpringBoot/resources/templates/screen/module/wmnt/")) {
                        Tool.outputResource("SpringBoot/resources/templates/screen/module/wmnt/" + name, Tool.createFile(wmnt, name));
                    }
                }
            }
        }
    }

    public void generateTestResources(File root, Project project) {
        HashMap<String, Object> ctx = new HashMap<String, Object>();

        ctx.put("domain", project.getDomain());
        ctx.put("projectName", project.getName());
        ctx.put("dataBase", project.getDatabase().toString());
        ctx.put("author", project.getAuthor());
        ctx.put("dBmapper", dBmapper);
        ctx.put("project", project);
        freeMarkerManager.outputTemp(Tool.createFile(root, "application.properties"), "SpringBoot/test/application.ftl", ctx);
        Tool.outputResource("SpringBoot/test/logback-spring.xml", Tool.createFile(root, "logback-spring.xml"));
    }

    public void generateTest(File root, Project project) {
        {
            File config = Tool.createPath(root, "config");
            config.mkdirs();
            HashMap<String, Object> ctx = new HashMap<String, Object>();
            ctx.put("domain", project.getDomain());
            ctx.put("moduleName", project.getName());
            ctx.put("author", project.getAuthor());
            File file = Tool.createFile(config, "TestConfig" + ".java");
            freeMarkerManager.outputTemp(file, "SpringBoot/test/TestConfig.ftl", ctx);
        }

        {
            HashMap<String, Object> ctx = new HashMap<String, Object>();
            ctx.put("domain", project.getDomain());
            ctx.put("moduleName", project.getName());
            ctx.put("author", project.getAuthor());
            File file = Tool.createFile(root, "UtilTest" + ".java");
            freeMarkerManager.outputTemp(file, "SpringBoot/test/UtilTest.java", ctx);
        }

        for (Module md : project.getModules()) {
            if (md.getNeedGenerate()) {
                File module = Tool.createPath(root, md.getModuleName());

                for (Table table : md.getTables()) {
                    HashMap<String, Object> ctx = new HashMap<String, Object>();

                    ctx.put("domain", project.getDomain());
                    ctx.put("module", md);
                    ctx.put("moduleName", md.getModuleName());
                    ctx.put("table", table);
                    ctx.put("author", md.getProjectAuthor());

                    File file = Tool.createFile(module, Tool.ABB2Abb(table.getTableName()) + "Test" + ".java");
                    freeMarkerManager.outputTemp(file, "SpringBoot/test/test.ftl", ctx);
                }
            }
        }

        if (project.getFrame().value() >= Frame.服务框架.value()) {
            HashMap<String, Object> ctx = new HashMap<String, Object>();

            ctx.put("domain", project.getDomain());
            ctx.put("moduleName", project.getName());
            ctx.put("author", project.getAuthor());
            File wsvr = Tool.createPath(root, "wsvr");

            for (String apiFile : ResourceUtil.getResourceFiles("/modules/SpringBoot/test/wsvr/")) {
                freeMarkerManager.outputTemp(Tool.createFile(wsvr, apiFile), "SpringBoot/test/wsvr/" + apiFile, ctx);
            }
        }

        if (project.getFrame().value() >= Frame.接口框架.value()) {
            HashMap<String, Object> ctx = new HashMap<String, Object>();

            ctx.put("domain", project.getDomain());
            ctx.put("moduleName", project.getName());
            ctx.put("author", project.getAuthor());
            File wsys = Tool.createPath(root, "wsys");

            for (String apiFile : ResourceUtil.getResourceFiles("/modules/SpringBoot/test/wsys/")) {
                if (apiFile.contains("Dict")) {
                    freeMarkerManager.outputTemp(Tool.createFile(wsys, apiFile), "SpringBoot/test/wsys/" + apiFile, ctx);
                }
            }
        }


        if (project.getFrame().value() >= Frame.网页框架.value()) {
            HashMap<String, Object> ctx = new HashMap<String, Object>();
            ctx.put("domain", project.getDomain());
            ctx.put("moduleName", project.getName());
            ctx.put("author", project.getAuthor());
            File wsys = Tool.createPath(root, "wsys");

            for (String apiFile : ResourceUtil.getResourceFiles("/modules/SpringBoot/test/wsys/")) {
                if (apiFile.contains("TokensTest") && project.getFrame().value() < Frame.接口框架.value()) {
                    continue;
                }
                freeMarkerManager.outputTemp(Tool.createFile(wsys, apiFile), "SpringBoot/test/wsys/" + apiFile, ctx);
            }
        }

        if (project.getFrame().value() >= Frame.接口框架.value()) {//数据初始化
            HashMap<String, Object> ctx = new HashMap<String, Object>();
            ctx.put("project", project);
            ctx.put("domain", project.getDomain());
            freeMarkerManager.outputTemp(Tool.createFile(root, "DataInit.java"), "SpringBoot/test/DataInit.java", ctx);
        }
        if (project.getFrame().value() >= Frame.网页框架.value()) {//数据初始化
            HashMap<String, Object> ctx = new HashMap<String, Object>();
            ctx.put("domain", project.getDomain());
            freeMarkerManager.outputTemp(Tool.createFile(root, "ExcelTest.java"), "SpringBoot/test/ExcelTest.java", ctx);
        }
    }
}
