package top.baogutang.generate.controller;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.map.HashedMap;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import top.baogutang.common.domain.Results;
import top.baogutang.generate.entity.ClassInfo;
import top.baogutang.generate.entity.ParamInfo;
import top.baogutang.generate.service.GeneratorService;
import top.baogutang.generate.util.MapUtil;
import top.baogutang.generate.util.TableParseUtil;
import top.baogutang.generate.util.ValueUtil;

import javax.annotation.Resource;
import java.util.Date;
import java.util.Map;

/**
 * 代码生成控制器
 *
 * @author niko
 */
@Controller
@Slf4j
public class GeneratorController {

    @Resource
    private ValueUtil valueUtil;

    @Resource
    private GeneratorService generatorService;

    @GetMapping("/")
    public ModelAndView defaultPage() {
        return new ModelAndView("index").addObject("value", valueUtil);
    }

    @GetMapping("/index")
    public ModelAndView indexPage() {
        return new ModelAndView("index").addObject("value", valueUtil);
    }

    @GetMapping("/main")
    public ModelAndView mainPage() {
        return new ModelAndView("main").addObject("value", valueUtil);
    }

    @RequestMapping("/template/all")
    @ResponseBody
    public Results<Map<String, String>> getAllTemplates() {
        String templates = generatorService.getTemplateConfig();
        Map<String, String> map = new HashedMap(2);
        map.put("templates", templates);
        return Results.ok(map);
    }

    @PostMapping("/code/generate")
    @ResponseBody
    public Results<Map<String, Map<String, String>>> generateCode(@RequestBody ParamInfo paramInfo) throws Exception {
        if (StringUtils.isEmpty(paramInfo.getTableSql())) {
            return Results.failed("表结构信息为空");
        }

        //1.Parse Table Structure 表结构解析
        ClassInfo classInfo = null;
        String dataType = MapUtil.getString(paramInfo.getOptions(), "dataType");
        if ("sql".equals(dataType) || dataType == null) {
            classInfo = TableParseUtil.processTableIntoClassInfo(paramInfo);
        } else if ("json".equals(dataType)) {
            //JSON模式：parse field from json string
            classInfo = TableParseUtil.processJsonToClassInfo(paramInfo);
            //INSERT SQL模式：parse field from insert sql
        } else if ("insert-sql".equals(dataType)) {
            classInfo = TableParseUtil.processInsertSqlToClassInfo(paramInfo);
            //正则表达式模式（非完善版本）：parse sql by regex
        } else if ("sql-regex".equals(dataType)) {
            classInfo = TableParseUtil.processTableToClassInfoByRegex(paramInfo);
            //默认模式：default parse sql by java
        }

        //2.Set the params 设置表格参数

        paramInfo.getOptions().put("classInfo", classInfo);
        paramInfo.getOptions().put("tableName", classInfo == null ? System.currentTimeMillis() : classInfo.getTableName());

        //log the generated table and filed size记录解析了什么表，有多少个字段

        //3.generate the code by freemarker templates with parameters . Freemarker根据参数和模板生成代码
        Map<String, String> result = generatorService.getResultByParams(paramInfo.getOptions());
        log.info("table:{} - time:{} ", MapUtil.getString(result, "tableName"), new Date());
        Map<String, Map<String, String>> map = new HashedMap(2);
        map.put("outputJson", result);
        return Results.ok(map);
    }

}
