package com.sifang.generate;

import com.google.common.collect.Maps;
import com.sifang.modules.sys.common.utils.FileUtils;
import com.sifang.modules.sys.common.utils.FreeMarkers;
import freemarker.template.Configuration;
import freemarker.template.Template;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.util.Map;

/**
 * 代码生成器
 * @version 2019-06-21
 */
public class TraderGenerate {

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

    public static void main(String[] args) throws Exception {

        // ========== ↓↓↓↓↓↓ 执行前请修改参数，谨慎执行。↓↓↓↓↓↓ ====================
        // 主要提供基本功能模块代码生成。
        // 目录生成结构：{packageName}/{moduleName}/{dao,entity,service,web}/{subModuleName}/{className}

        // packageName 包名，这里如果更改包名，请在applicationContext.xml和spring-mvc.xml中配置base-package、packagesToScan属性，来指定多个（共4处需要修改）。
        String packageName = "com.sifang.modules";
        String moduleName = "insurance";            // 模块名，例：sys
        String subModuleName = "";                // 子模块名（可选）
        String className = "CrmInsuranceList";        // 类名，例：user
        String classAuthor = "DQChen";            // 类作者，例：Ivan
        String functionName = "保险信息";            // 功能名，例：用户

        if (StringUtils.isBlank(moduleName) || StringUtils.isBlank(moduleName)
                || StringUtils.isBlank(className) || StringUtils.isBlank(functionName)) {
            logger.error("参数设置错误：包名、模块名、类名、功能名不能为空。");
            return;
        }

        // 获取文件分隔符
        String separator = File.separator;

        // 获取工程路径
        String projectPath = "E:\\IDEA_Workspace\\the-lyui-frameworks";

        // 模板文件路径
        String tplPath = StringUtils.replace(projectPath + "/src/main/java/com/sifang/generate/template", "/", separator);
        logger.info("Template Path: {}", tplPath);

        // Java文件路径
        String javaPath = StringUtils.replaceEach(projectPath + "/src/main/java/" + StringUtils.lowerCase(packageName),
                new String[]{"/", "."}, new String[]{separator, separator});
        logger.info("Java Path: {}", javaPath);

        // 代码模板配置
        Configuration cfg = new Configuration();
        cfg.setDefaultEncoding("UTF-8");
        cfg.setDirectoryForTemplateLoading(new File(tplPath));

        // 定义模板变量
        Map<String, String> model = Maps.newHashMap();
        model.put("packageName", StringUtils.lowerCase(packageName));
        model.put("moduleName", StringUtils.lowerCase(moduleName));
        model.put("subModuleName", StringUtils.isNotBlank(subModuleName) ? "." + StringUtils.lowerCase(subModuleName) : "");
        model.put("className", StringUtils.uncapitalize(className));
        model.put("ClassName", StringUtils.capitalize(className));
        model.put("classAuthor", StringUtils.isNotBlank(classAuthor) ? classAuthor : "Generate Tools");
        model.put("classVersion", "");
        model.put("functionName", functionName);
        model.put("tableName", model.get("moduleName") + (StringUtils.isNotBlank(subModuleName)
                ? "_" + StringUtils.lowerCase(subModuleName) : "") + "_" + model.get("className"));
        model.put("urlPrefix", model.get("moduleName") + (StringUtils.isNotBlank(subModuleName)
                ? "/" + StringUtils.lowerCase(subModuleName) : "") + "/" + model.get("className"));
        model.put("viewPrefix", //StringUtils.substringAfterLast(model.get("packageName"),".")+"/"+
                model.get("urlPrefix"));
        model.put("permissionPrefix", model.get("moduleName") + (StringUtils.isNotBlank(subModuleName)
                ? ":" + StringUtils.lowerCase(subModuleName) : "") + ":" + model.get("className"));

        // 生成 Entity
        Template template = cfg.getTemplate("entity.ftl");
        String content = FreeMarkers.renderTemplate(template, model);
        String filePath = javaPath + separator + model.get("moduleName") + separator + "entity"
                + separator + StringUtils.lowerCase(subModuleName) + separator + model.get("ClassName") + ".java";
        writeFile(content, filePath);
        logger.info("Entity: {}", filePath);

        // 生成 Dao
        template = cfg.getTemplate("dao.ftl");
        content = FreeMarkers.renderTemplate(template, model);
        filePath = javaPath + separator + model.get("moduleName") + separator + "dao" + separator
                + StringUtils.lowerCase(subModuleName) + separator + model.get("ClassName") + "Dao.java";
        writeFile(content, filePath);
        logger.info("Dao: {}", filePath);

        // 生成 Service
        template = cfg.getTemplate("service.ftl");
        content = FreeMarkers.renderTemplate(template, model);
        filePath = javaPath + separator + model.get("moduleName") + separator + "service" + separator
                + StringUtils.lowerCase(subModuleName) + separator + model.get("ClassName") + "Service.java";
        writeFile(content, filePath);
        logger.info("Service: {}", filePath);

        // 生成 Controller
        template = cfg.getTemplate("controller.ftl");
        content = FreeMarkers.renderTemplate(template, model);
        filePath = javaPath + separator + model.get("moduleName") + separator + "web" + separator
                + StringUtils.lowerCase(subModuleName) + separator + model.get("ClassName") + "Controller.java";
        writeFile(content, filePath);
        logger.info("Controller: {}", filePath);

        writeFile(content, filePath);
        logger.info("ViewList: {}", filePath);

        logger.info("Generate Success.");
    }

    /**
     * 将内容写入文件
     */
    public static void writeFile(String content, String filePath) {
        try {
            if (FileUtils.createFile(filePath)) {
                FileOutputStream fos = new FileOutputStream(filePath);
                Writer writer = new OutputStreamWriter(fos, "UTF-8");
                BufferedWriter bufferedWriter = new BufferedWriter(writer);
                bufferedWriter.write(content);
                bufferedWriter.close();
                writer.close();
            } else {
                logger.info("生成失败，文件已存在！");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
