package cn.stylefeng.team.generator.sdk.template.factory;

import cn.hutool.core.io.IoUtil;
import cn.stylefeng.roses.kernel.rule.exception.base.ServiceException;
import cn.stylefeng.team.generator.api.enums.GeneratorTypeEnum;
import cn.stylefeng.team.generator.api.exception.enums.GenerationExceptionEnum;
import cn.stylefeng.team.generator.api.pojo.template.GeneratorTemplate;
import cn.stylefeng.team.generator.api.pojo.template.GeneratorTemplateGroup;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

public class TemplateFactory {

    public static GeneratorTemplateGroup proxyCreateTemplate(GeneratorTypeEnum generatorTypeEnum) {
        if (GeneratorTypeEnum.SINGLE_TABLE_BACKEND.equals(generatorTypeEnum)) {
            return createBackendSingleTemplate();
        } else if (GeneratorTypeEnum.SINGLE_TABLE_FRONT.equals(generatorTypeEnum)) {
            return createFrontendTemplate();
        } else if (GeneratorTypeEnum.BIZ_FRONT_GENERATE.equals(generatorTypeEnum)) {
            return createBizFrontendTemplate();
        } else if (GeneratorTypeEnum.CREAT_SQL.equals(generatorTypeEnum)) {
            return createCreatSqlTemplates();
        } else if (GeneratorTypeEnum.INSERT_SYS_DICT_SQL.equals(generatorTypeEnum)) {
            return createInsertSysDictSqlTemplate();
        } else if (GeneratorTypeEnum.JAVA_ENUM.equals(generatorTypeEnum)) {
            return createJavaEnumTemplate();
        } else if (GeneratorTypeEnum.ALTER_TABLE.equals(generatorTypeEnum)) {
            return createAlterSqlTemplate();
        }

        throw new ServiceException(GenerationExceptionEnum.CANT_FIND_TEMPLATE);
    }

    public static GeneratorTemplateGroup createFrontendTemplate() {

        GeneratorTemplateGroup generatorTemplateGroup = new GeneratorTemplateGroup();

        generatorTemplateGroup.setGeneratorTypeEnum(GeneratorTypeEnum.SINGLE_TABLE_FRONT);

        List<GeneratorTemplate> generatorTemplates = new ArrayList<>();

        generatorTemplates.add(new GeneratorTemplate("/api", "Api.js",
                getResourceContent("templates/guns-v8/frontend/api.js.btl")));

        generatorTemplates.add(new GeneratorTemplate("/", ".vue",
                getResourceContent("templates/guns-v8/frontend/index.vue.btl")));

        generatorTemplates.add(new GeneratorTemplate("/components", "-add-edit.vue",
                getResourceContent("templates/guns-v8/frontend/add-edit.vue.btl")));

        generatorTemplates.add(new GeneratorTemplate("/components", "-form.vue",
                getResourceContent("templates/guns-v8/frontend/form.vue.btl")));

        generatorTemplateGroup.setGeneratorTemplates(generatorTemplates);

        return generatorTemplateGroup;
    }

    public static GeneratorTemplateGroup createBackendSingleTemplate() {

        GeneratorTemplateGroup generatorTemplateGroup = new GeneratorTemplateGroup();

        generatorTemplateGroup.setGeneratorTypeEnum(GeneratorTypeEnum.SINGLE_TABLE_BACKEND);

        List<GeneratorTemplate> generatorTemplates = new ArrayList<>();
        generatorTemplates.add(new GeneratorTemplate("/controller", "Controller.java",
                getResourceContent("templates/guns-v8/backend/controller.java.btl")));

        generatorTemplates.add(new GeneratorTemplate("/entity", ".java",
                getResourceContent("templates/guns-v8/backend/entity.java.btl")));

        generatorTemplates.add(new GeneratorTemplate("/enums", "ExceptionEnum.java",
                getResourceContent("templates/guns-v8/backend/enum.java.btl")));

        generatorTemplates.add(new GeneratorTemplate("/mapper", "Mapper.java",
                getResourceContent("templates/guns-v8/backend/mapper.java.btl")));

        generatorTemplates.add(new GeneratorTemplate("/mapper/mapping", "Mapper.xml",
                getResourceContent("templates/guns-v8/backend/mapping.xml.btl")));

        generatorTemplates.add(new GeneratorTemplate("/pojo/request", "Request.java",
                getResourceContent("templates/guns-v8/backend/request-pojo.java.btl")));

        generatorTemplates.add(new GeneratorTemplate("/pojo/response", "Vo.java",
                getResourceContent("templates/guns-v8/backend/response-vo.java.btl")));

        generatorTemplates.add(new GeneratorTemplate("/service", "Service.java",
                getResourceContent("templates/guns-v8/backend/service.java.btl")));

        generatorTemplates.add(new GeneratorTemplate("/service/impl", "ServiceImpl.java",
                getResourceContent("templates/guns-v8/backend/service-impl.java.btl")));

        generatorTemplateGroup.setGeneratorTemplates(generatorTemplates);

        return generatorTemplateGroup;
    }

    public static GeneratorTemplateGroup createCreatSqlTemplates() {

        GeneratorTemplateGroup generatorTemplateGroup = new GeneratorTemplateGroup();

        generatorTemplateGroup.setGeneratorTypeEnum(GeneratorTypeEnum.CREAT_SQL);

        List<GeneratorTemplate> generatorTemplates = new ArrayList<>();
        generatorTemplates.add(new GeneratorTemplate("/mysql", ".mysql",
                getResourceContent("templates/guns-v8/sql/mysql.sql.btl")));

        generatorTemplates.add(new GeneratorTemplate("/oracle", ".oracle",
                getResourceContent("templates/guns-v8/sql/oracle.sql.btl")));

        generatorTemplates.add(new GeneratorTemplate("/pgsql", ".pgsql",
                getResourceContent("templates/guns-v8/sql/pgsql.sql.btl")));

        generatorTemplateGroup.setGeneratorTemplates(generatorTemplates);

        return generatorTemplateGroup;
    }

    public static GeneratorTemplateGroup createInsertSysDictSqlTemplate() {

        GeneratorTemplateGroup generatorTemplateGroup = new GeneratorTemplateGroup();

        generatorTemplateGroup.setGeneratorTypeEnum(GeneratorTypeEnum.INSERT_SYS_DICT_SQL);

        List<GeneratorTemplate> generatorTemplates = new ArrayList<>();
        generatorTemplates.add(new GeneratorTemplate("/insert-sys-dict", ".sql",
                getResourceContent("templates/insert-dict/insert-sys-dict.sql.btl")));

        generatorTemplateGroup.setGeneratorTemplates(generatorTemplates);

        return generatorTemplateGroup;
    }

    public static GeneratorTemplateGroup createJavaEnumTemplate() {

        GeneratorTemplateGroup generatorTemplateGroup = new GeneratorTemplateGroup();

        generatorTemplateGroup.setGeneratorTypeEnum(GeneratorTypeEnum.JAVA_ENUM);

        List<GeneratorTemplate> generatorTemplates = new ArrayList<>();
        generatorTemplates.add(new GeneratorTemplate("/javaEnums", ".java",
                getResourceContent("templates/java-model/enum.java.btl")));

        generatorTemplateGroup.setGeneratorTemplates(generatorTemplates);

        return generatorTemplateGroup;
    }

    public static String getResourceContent(String resourcePath) {
        InputStream inputStream = null;
        try {
            inputStream = TemplateFactory.class.getResourceAsStream("/" + resourcePath);
            return IoUtil.readUtf8(inputStream);
        } finally {
            IoUtil.close(inputStream);
        }
    }

    private static GeneratorTemplateGroup createBizFrontendTemplate() {
        GeneratorTemplateGroup generatorTemplateGroup = new GeneratorTemplateGroup();

        generatorTemplateGroup.setGeneratorTypeEnum(GeneratorTypeEnum.BIZ_FRONT_GENERATE);

        List<GeneratorTemplate> generatorTemplates = new ArrayList<>();

        generatorTemplates.add(new GeneratorTemplate("/api", "Api.js",
                getResourceContent("templates/guns-v8-biz/frontend/api.js.btl")));

        generatorTemplates.add(new GeneratorTemplate("/", ".vue",
                getResourceContent("templates/guns-v8-biz/frontend/index.vue.btl")));

        generatorTemplates.add(new GeneratorTemplate("/components", "-add-edit.vue",
                getResourceContent("templates/guns-v8-biz/frontend/add-edit.vue.btl")));

        generatorTemplates.add(new GeneratorTemplate("/components", "-detail.vue",
                getResourceContent("templates/guns-v8-biz/frontend/detail.vue.btl")));

        generatorTemplates.add(new GeneratorTemplate("/components", "-form.vue",
                getResourceContent("templates/guns-v8-biz/frontend/form.vue.btl")));

        generatorTemplateGroup.setGeneratorTemplates(generatorTemplates);

        return generatorTemplateGroup;
    }

    public static GeneratorTemplateGroup createAlterSqlTemplate() {

        GeneratorTemplateGroup generatorTemplateGroup = new GeneratorTemplateGroup();

        generatorTemplateGroup.setGeneratorTypeEnum(GeneratorTypeEnum.ALTER_TABLE);

        List<GeneratorTemplate> generatorTemplates = new ArrayList<>();
        generatorTemplates.add(new GeneratorTemplate("/alter-table", ".sql",
                getResourceContent("templates/alter-table/mysql-alter.sql.btl")));

        generatorTemplateGroup.setGeneratorTemplates(generatorTemplates);

        return generatorTemplateGroup;
    }

}
