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

import xyz.wbsite.dbtool.javafx.manger.ProjectManager;
import xyz.wbsite.dbtool.javafx.manger.FreeMarkerManager;
import xyz.wbsite.dbtool.javafx.manger.ManagerFactory;
import xyz.wbsite.dbtool.javafx.po.AbstractDBmapper;
import xyz.wbsite.dbtool.javafx.po.Api;
import xyz.wbsite.dbtool.javafx.tool.JavaClassReader;
import xyz.wbsite.dbtool.javafx.tool.JavaEnumReader;
import xyz.wbsite.dbtool.javafx.tool.Tool;

import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.Callable;

public class ApiCallable implements Callable {

    private File api;
    private File req;
    private File rsp;
    private File ent;
    private File enums;
    private List<Api> apiList;
    private Tool tool = new Tool();

    private FreeMarkerManager freeMarkerManager;

    public ApiCallable(File api, File req, File rsp, File ent, File enums, List<Api> apiList) {
        this.api = api;
        this.req = req;
        this.rsp = rsp;
        this.ent = ent;
        this.enums = enums;
        this.apiList = apiList;
        this.freeMarkerManager = ManagerFactory.getFreeMarkerManager();
    }

    private AbstractDBmapper dBmapper;

    public Boolean call() throws Exception {
        if (!api.exists()) {
            api.mkdir();
        } else {
            Tool.clear(api);
        }

        dBmapper = ProjectManager.dBmapper;

        File domain;
        File testdomain;
        File request;
        File response;
        File entity;
        File enumeration;

        StringBuffer sbmain = new StringBuffer("");
        sbmain.append(this.api.getPath() + File.separator);
        sbmain.append("src" + File.separator);
        sbmain.append("main" + File.separator);
        sbmain.append("java" + File.separator);

        StringBuffer sbtest = new StringBuffer("");
        sbtest.append(this.api.getPath() + File.separator);
        sbtest.append("src" + File.separator);
        sbtest.append("test" + File.separator);
        sbtest.append("java" + File.separator);

        JavaClassReader javaClass = new JavaClassReader(apiList.get(0).getReq());
        String[] split = javaClass.getDomainName().split("\\.");

        for (String s1 : split) {
            sbmain.append(s1 + File.separator);
            sbtest.append(s1 + File.separator);
        }

        domain = new File(sbmain.toString());
        domain.mkdirs();
        testdomain = new File(sbtest.toString());
        testdomain.mkdirs();
        request = new File(domain, "request");
        request.mkdirs();
        response = new File(domain, "response");
        response.mkdirs();
        entity = new File(domain, "entity");
        entity.mkdirs();
        enumeration = new File(domain, "enums");
        enumeration.mkdirs();

        {
            System.out.println("生成模块:Pom");
            HashMap<String, Object> ctx = new HashMap<String, Object>();
            ctx.put("api", api.getName());
            File file = new File(api, "pom.xml");
            freeMarkerManager.outputTemp(file, "Java_api/pom.ftl", ctx);
        }


        Set<String> managerList = new HashSet<>();
        List<Method> methodList = new ArrayList<>();

        for (Api api : apiList) {
            if (api.isCheck()) {

                try {
                    //region 生成request
                    JavaClassReader javaClassReader = new JavaClassReader(api.getReq());
                    for (int i = 0; i < javaClassReader.getImportList().size(); i++) {
                        String s = javaClassReader.getImportList().get(i);
                        if (s.contains(".api.entity.")) {
                            javaClassReader.getImportList().set(i, s.replaceAll("\\.api\\.entity\\.", ".entity."));
                        }
                    }

                    Method method = new Method();
                    method.setStringMethod(api.getMethod());
                    method.setRequest(javaClassReader.getClassName());
                    method.setTarget(Tool.getRequestTarget(javaClassReader.getClassName()));
                    method.setMethod(Tool.getRequestAction(javaClassReader.getClassName()));
                    method.setManager(Tool.getRequestTarget(javaClassReader.getClassName()) + "Manager");
                    methodList.add(method);

                    managerList.add(method.getManager());

                    {
                        HashMap<String, Object> ctx = new HashMap<String, Object>();
                        ctx.put("package", "package " + javaClassReader.getDomainName() + "." + javaClassReader.getModuleName() + "." + "request;");
                        ctx.put("domain", javaClassReader.getDomainName());
                        ctx.put("module", javaClassReader.getModuleName());
                        ctx.put("importList", javaClassReader.getImportList());
                        ctx.put("annotation", javaClassReader.getAnnotationList());
                        ctx.put("className", javaClassReader.getClassName().replaceAll("Request", ""));
                        ctx.put("body", javaClassReader.getBody());
                        ctx.put("tool", tool);
                        ctx.put("hasList", javaClassReader.isHasList());
                        ctx.put("findOrSearchflag", javaClassReader.getFindOrSearchflag());
                        File file = new File(request.getAbsolutePath(), api.getReq().getName());

                        freeMarkerManager.outputTemp(file, "Java_api/module/request/request.ftl", ctx);
                        System.out.println("生成文件" + file.getName() + "成功");
                    }
                    //endregion
                } catch (IOException e) {
                    e.printStackTrace();
                }


                try {
                    //region 生成response
                    JavaClassReader javaClassReader = new JavaClassReader(api.getRsp());
                    for (int i = 0; i < javaClassReader.getImportList().size(); i++) {
                        String import_ = javaClassReader.getImportList().get(i);
                        if (import_.contains(".api.entity.")) {
                            javaClassReader.getImportList().set(i, import_.replaceAll("\\.api\\.entity\\.", ".entity."));
                        }
                    }

                    {
                        HashMap<String, Object> ctx = new HashMap<String, Object>();
                        ctx.put("package", "package " + javaClassReader.getDomainName() + "." + javaClassReader.getModuleName() + "." + "request;");
                        ctx.put("domain", javaClassReader.getDomainName());
                        ctx.put("module", javaClassReader.getModuleName());
                        ctx.put("importList", javaClassReader.getImportList());
                        ctx.put("annotation", javaClassReader.getAnnotationList());
                        ctx.put("className", javaClassReader.getClassName().replaceAll("Response", ""));
                        ctx.put("body", javaClassReader.getBody());
                        ctx.put("tool", tool);
                        ctx.put("hasList", javaClassReader.isHasList());
                        ctx.put("Tclass", javaClassReader.getTclass());
                        File file = new File(response.getAbsolutePath(), api.getRsp().getName().replaceAll("Request", "Response"));

                        freeMarkerManager.outputTemp(file, "Java_api/module/response/response.ftl", ctx);
                        System.out.println("生成文件" + api.getRsp().getName() + "成功");
                    }
                    //endregion
                } catch (IOException e) {
                    e.printStackTrace();
                }

                for (String s : api.getDepReq()) {
                    try {
                        File f = new File(req.getAbsolutePath(), s + ".java");
                        if (!f.exists()) {
                            System.err.println("文件" + f.getAbsolutePath() + "不存在");
                            continue;
                        }
                        JavaClassReader javaClassReader = new JavaClassReader(f);
                        for (int i = 0; i < javaClassReader.getImportList().size(); i++) {
                            String import_ = javaClassReader.getImportList().get(i);
                            if (import_.contains(".api.entity.")) {
                                javaClassReader.getImportList().set(i, import_.replaceAll("\\.api\\.entity\\.", ".entity."));
                            }
                        }

                        Method method = new Method();
                        method.setStringMethod(api.getMethod());
                        method.setRequest(javaClassReader.getClassName());
                        method.setTarget(Tool.getRequestTarget(javaClassReader.getClassName()));
                        method.setMethod(Tool.getRequestAction(javaClassReader.getClassName()));
                        method.setManager(Tool.getRequestTarget(javaClassReader.getClassName()) + "Manager");

                        {
                            HashMap<String, Object> ctx = new HashMap<String, Object>();
                            ctx.put("package", "package " + javaClassReader.getDomainName() + "." + javaClassReader.getModuleName() + "." + "request;");
                            ctx.put("domain", javaClassReader.getDomainName());
                            ctx.put("module", javaClassReader.getModuleName());
                            ctx.put("importList", javaClassReader.getImportList());
                            ctx.put("annotation", javaClassReader.getAnnotationList());
                            ctx.put("className", javaClassReader.getClassName().replaceAll("Request", ""));
                            ctx.put("body", javaClassReader.getBody());
                            ctx.put("tool", tool);
                            ctx.put("hasList", javaClassReader.isHasList());
                            ctx.put("findOrSearchflag", javaClassReader.getFindOrSearchflag());
                            File file = new File(request.getAbsolutePath(), f.getName());

                            freeMarkerManager.outputTemp(file, "Java_api/module/request/request.ftl", ctx);
                            System.out.println("生成文件" + file.getName() + "成功");
                        }
                        //endregion
                    } catch (IOException e) {
                        e.printStackTrace();
                    }

                    try {
                        File f = new File(rsp.getAbsolutePath(), s.replaceAll("Request", "Response.java"));
                        if (!f.exists()) {
                            System.err.println("文件" + f.getAbsolutePath() + "不存在");
                        }
                        JavaClassReader javaClassReader = new JavaClassReader(f);
                        for (int i = 0; i < javaClassReader.getImportList().size(); i++) {
                            String import_ = javaClassReader.getImportList().get(i);
                            if (import_.contains(".api.entity.")) {
                                javaClassReader.getImportList().set(i, import_.replaceAll("\\.api\\.entity\\.", ".entity."));
                            }
                        }

                        {
                            HashMap<String, Object> ctx = new HashMap<String, Object>();
                            ctx.put("package", "package " + javaClassReader.getDomainName() + "." + javaClassReader.getModuleName() + "." + "request;");
                            ctx.put("domain", javaClassReader.getDomainName());
                            ctx.put("module", javaClassReader.getModuleName());
                            ctx.put("importList", javaClassReader.getImportList());
                            ctx.put("annotation", javaClassReader.getAnnotationList());
                            ctx.put("className", javaClassReader.getClassName().replaceAll("Response", ""));
                            ctx.put("body", javaClassReader.getBody());
                            ctx.put("tool", tool);
                            ctx.put("hasList", javaClassReader.isHasList());
                            ctx.put("Tclass", javaClassReader.getTclass());
                            File file = new File(response.getAbsolutePath(), f.getName());

                            freeMarkerManager.outputTemp(file, "Java_api/module/response/response.ftl", ctx);
                            System.out.println("生成文件" + api.getRsp().getName() + "成功");
                        }
                        //endregion
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }

                for (String s : api.getDepEnt()) {

                    try {
                        File f = new File(ent.getAbsolutePath(), s + ".java");
                        if (!f.exists()) {
                            System.out.println("文件" + f.getAbsolutePath() + "不存在");
                            continue;
                        }
                        JavaClassReader javaClassReader = new JavaClassReader(f);
                        for (int i = 0; i < javaClassReader.getImportList().size(); i++) {
                            String import_ = javaClassReader.getImportList().get(i);
                            if (import_.contains(".api.entity.")) {
                                javaClassReader.getImportList().set(i, import_.replaceAll("\\.api\\.entity\\.", ".entity."));
                            }
                        }

                        {
                            HashMap<String, Object> ctx = new HashMap<String, Object>();
                            ctx.put("package", "package " + javaClassReader.getDomainName() + "." + javaClassReader.getModuleName() + "." + "request;");
                            ctx.put("domain", javaClassReader.getDomainName());
                            ctx.put("module", javaClassReader.getModuleName());
                            ctx.put("importList", javaClassReader.getImportList());
                            ctx.put("annotation", javaClassReader.getAnnotationList());
                            ctx.put("className", javaClassReader.getClassName().replaceAll("Entity", ""));
                            ctx.put("body", javaClassReader.getBody());
                            ctx.put("tool", tool);
                            File file = new File(entity.getAbsolutePath(), f.getName());
                            freeMarkerManager.outputTemp(file, "Java_api/module/entity/entity.ftl", ctx);
                            System.out.println("生成文件" + file.getName() + "成功");
                        }
                        //endregion
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }

                for (String s : api.getDepEnum()) {
                    try {
                        File f = new File(enums, s + ".java");
                        if (!f.exists()) {
                            System.err.println("文件" + f.getAbsolutePath() + "不存在");
                            continue;
                        }
                        JavaEnumReader javaEnumReader = new JavaEnumReader(f);

                        {
                            HashMap<String, Object> ctx = new HashMap<String, Object>();
                            ctx.put("package", "package " + javaEnumReader.getDomainName() + "." + javaEnumReader.getModuleName() + "." + "enums;");
                            ctx.put("domain", javaEnumReader.getDomainName());
                            ctx.put("module", javaEnumReader.getModuleName());
                            ctx.put("annotation", javaEnumReader.getAnnotationList());
                            ctx.put("className", javaEnumReader.getClassName());
                            ctx.put("body", javaEnumReader.getBody());
                            ctx.put("tool", tool);

                            File file = new File(enumeration, f.getName());
                            freeMarkerManager.outputTemp(file, "Java_api/module/enums/type.ftl", ctx);
                            System.out.println("生成文件" + file.getName() + "成功");
                        }
                        //endregion

                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }

        {
            System.out.println("生成模块:ApiController");
            HashMap<String, Object> ctx = new HashMap<String, Object>();
            ctx.put("tool", tool);
            ctx.put("domain", javaClass.getDomainName());
            ctx.put("module", javaClass.getModuleName());
            ctx.put("managerList", managerList);
            ctx.put("methodList", methodList);
            File file = new File(domain.getAbsolutePath() + File.separator + "ApiController.java");
            freeMarkerManager.outputTemp(file, "Java_api/module/controller/ApiController.ftl", ctx);
        }

        {
            System.out.println("生成基础类");
            HashMap<String, Object> ctx = new HashMap<String, Object>();
            ctx.put("domain", javaClass.getDomainName());
            ctx.put("module", javaClass.getModuleName());
            {
                File file = new File(domain, "ApiEntity.java");
                freeMarkerManager.outputTemp(file, "/Java_api/ApiEntity.ftl", ctx);
            }
            {
                File file = new File(domain, "AESUtil.java");
                freeMarkerManager.outputTemp(file, "/Java_api/AESUtil.ftl", ctx);
            }
            {
                File file = new File(domain, "ApiClient.java");
                freeMarkerManager.outputTemp(file, "/Java_api/ApiClient.ftl", ctx);
            }
            {
                File file = new File(domain, "ApiRequest.java");
                freeMarkerManager.outputTemp(file, "/Java_api/ApiRequest.ftl", ctx);
            }
            {
                File file = new File(domain, "ApiFindRequest.java");
                freeMarkerManager.outputTemp(file, "/Java_api/ApiFindRequest.ftl", ctx);
            }
            {
                File file = new File(domain, "ApiSearchRequest.java");
                freeMarkerManager.outputTemp(file, "/Java_api/ApiSearchRequest.ftl", ctx);
            }
            {
                File file = new File(domain, "ApiResponse.java");
                freeMarkerManager.outputTemp(file, "/Java_api/ApiResponse.ftl", ctx);
            }
            {
                File file = new File(domain, "ApiFindResponse.java");
                freeMarkerManager.outputTemp(file, "/Java_api/ApiFindResponse.ftl", ctx);
            }
            {
                File file = new File(domain, "Base64Util.java");
                freeMarkerManager.outputTemp(file, "/Java_api/Base64Util.ftl", ctx);
            }
            {
                File file = new File(domain, "DownloadUtil.java");
                freeMarkerManager.outputTemp(file, "/Java_api/DownloadUtil.ftl", ctx);
            }
            {
                File file = new File(domain, "Error.java");
                freeMarkerManager.outputTemp(file, "/Java_api/Error.ftl", ctx);
            }
            {
                File file = new File(domain, "ErrorType.java");
                freeMarkerManager.outputTemp(file, "/Java_api/ErrorType.ftl", ctx);
            }
            {
                File file = new File(domain, "FileUploadRequest.java");
                freeMarkerManager.outputTemp(file, "/Java_api/FileUploadRequest.ftl", ctx);
            }
            {
                File file = new File(domain, "FileUploadResponse.java");
                freeMarkerManager.outputTemp(file, "/Java_api/FileUploadResponse.ftl", ctx);
            }
            {
                File file = new File(domain, "MapperUtil.java");
                freeMarkerManager.outputTemp(file, "/Java_api/MapperUtil.ftl", ctx);
            }
            {
                File file = new File(domain, "MD5Util.java");
                freeMarkerManager.outputTemp(file, "/Java_api/MD5Util.ftl", ctx);
            }
            {
                File file = new File(domain, "RSAUtil.java");
                freeMarkerManager.outputTemp(file, "/Java_api/RSAUtil.ftl", ctx);
            }
            {
                File file = new File(domain, "ProgressRequestBody.java");
                freeMarkerManager.outputTemp(file, "/Java_api/ProgressRequestBody.ftl", ctx);
            }

            {
                File file = new File(domain, "SortType.java");
                freeMarkerManager.outputTemp(file, "/Java_api/SortType.ftl", ctx);
            }

            {
                File file = new File(domain, "StringUtils.java");
                freeMarkerManager.outputTemp(file, "/Java_api/StringUtils.ftl", ctx);
            }

            //4.0.1 去掉验证 减少体积
//        {
//            File file = new File(frameWork , "ValidationUtil.java");
//            freeMarkerManager.outputTemp(file, "/Java_api/ValidationUtil.ftl", ctx);
//        }

        }

        {//生成Test
            System.out.println("生成模块:Test");
            HashMap<String, Object> ctx = new HashMap<String, Object>();
            ctx.put("tool", tool);
            ctx.put("domain", javaClass.getDomainName());
            ctx.put("module", javaClass.getModuleName());
            ctx.put("managerList", managerList);
            ctx.put("methodList", methodList);
            ctx.put("apiList", apiList);
            freeMarkerManager.outputTemp(new File(testdomain.getAbsolutePath(), "ApiTest.java"), "Java_api/ApiTest.ftl", ctx);
        }

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


    public class Method {
        private String request;
        private String stringMethod;
        private String manager;
        private String method;
        private String target;

        public String getRequest() {
            return request;
        }

        public void setRequest(String request) {
            this.request = request;
        }

        public String getTarget() {
            return target;
        }

        public void setTarget(String target) {
            this.target = target;
        }

        public String getStringMethod() {
            return stringMethod;
        }

        public void setStringMethod(String stringMethod) {
            this.stringMethod = stringMethod;
        }

        public String getManager() {
            return manager;
        }

        public void setManager(String manager) {
            this.manager = manager;
        }

        public String getMethod() {
            return method;
        }

        public void setMethod(String method) {
            this.method = method;
        }
    }
}
