package cn.feast.coding.service.generator;

import cn.feast.coding.generator.Generator;
import cn.feast.coding.generator.factory.GeneratorFactory;
import cn.feast.coding.mapper.generator.ColunmMapper;
import cn.feast.coding.mapper.generator.ProjectMapper;
import cn.feast.coding.mapper.generator.TableMapper;
import cn.feast.coding.model.generator.*;
import cn.feast.coding.tools.Contants;
import cn.feast.coding.tools.ZipTools;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletRequest;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;

import static cn.feast.coding.tools.StringUtils.uncapFirst;


@Service
public class GeneratorService {
    @Autowired
    private GeneratorFactory generatorFactory;
    private Generator generator;
    @Autowired
    private TableMapper tableMapper;
    @Autowired
    private ColunmMapper colunmMapper;
    @Autowired
    private ProjectMapper projectMapper;
    @Autowired
    private ModuleProjectService moduleProjectService;

    public void generator(Project project, HttpServletRequest request) {
        project = projectMapper.queryById(project.getId());
        List<Table> tableList = tableMapper.queryByProject(project.getId());
        generator(project, tableList, request);
    }

    public void generator(Project project, List<Table> tableList, HttpServletRequest request) {
        Map<String, Object> map = new Hashtable<>();
        map.put("project", project);
        map.put("tableList", tableList);
        generator(map, request);
    }

    public void generator(Map<String, Object> map, HttpServletRequest request) {
        Project project = (Project) map.get("project");
        //获取项目框架
        String templateType = project.getTemplateType();
        //添加功能模块支持
        addModuleSupport(project, map);
        //生成代码
        generator = generatorFactory.getGenerator(templateType);
        generate(map, templateType);
        //打包生成文件
        packageGenerateFiles(project, request);
    }

    /**
     * 打包生成代码
     *
     * @param project
     * @param request
     */
    public void packageGenerateFiles(Project project, HttpServletRequest request) {
        String fileName = "OpenPark";
        if(StringUtils.isNotEmpty(project.getProjectFileName())){
            fileName = project.getProjectFileName();
        }
        String path = request.getSession().getServletContext().getRealPath("/" + fileName);
        String zipFilPath = request.getSession().getServletContext().getRealPath("/zip") + "/" + project.getProjectName() + ".zip";
        ZipTools.zipMultiFile(path, zipFilPath, true);
    }

    private void generate(Map<String, Object> map, String templateType) {
        List<Table> tableList = (List<Table>) map.get("tableList");
        for (Table table : tableList) {
            initMap(table, map, templateType);
            generator.generateController(map);
            generator.generateDao(map);
            generator.generateDaoImpl(map);
            generator.generateModel(map);
            generator.generateService(map);
            generator.generateIService(map);
            generator.generateJsp(map);
        }
        generator.generateIndex(map);
        generator.generateUtils(map);
        generator.generateCommon(map);
        generator.generateDefined(map);
    }

    private void addModuleSupport(Project project, Map<String, Object> map) {
        Integer projectId = project.getId();
        String templateType = project.getTemplateType();
        //登录功能
        List<ModuleProject> loginList = addLoginModuleSupport(projectId, templateType);
        if (!loginList.isEmpty()) {
            map.put("loginModule", loginList.get(0));
        }
        //注册功能
        List<ModuleProject> registerList = addRegisterModuleSupport(projectId, templateType);
        if (!registerList.isEmpty()) {
            map.put("registerModule", registerList.get(0));
        }
        //修改密码功能
        List<ModuleProject> passwordList = addPasswordModuleSupport(projectId, templateType);
        if (!passwordList.isEmpty()) {
            map.put("passwordModule", passwordList.get(0));
        }
        //查询功能
        List<ModuleProject> queryList = addQueryModuleSupport(projectId, templateType);
        if (!queryList.isEmpty()) {
            map.put("queryModule", queryList);
        }
    }

    private List<ModuleProject> addLoginModuleSupport(Integer projectId, String templateType) {
        List<ModuleProject> loginList = moduleProjectService.queryByProjectAndModule(projectId, Contants.LOGIN_MODULE);
        if (!loginList.isEmpty()) {
            for (ModuleProject mp : loginList) {
                //兼容ssh
                mp.frameAdapter(templateType);
            }
        }
        return loginList;
    }

    private List<ModuleProject> addRegisterModuleSupport(Integer projectId, String templateType) {
        List<ModuleProject> registerList = moduleProjectService.queryByProjectAndModule(projectId, Contants.REGISTER_MODULE);
        if (!registerList.isEmpty()) {
            for (ModuleProject mp : registerList) {
                //兼容ssh
                mp.frameAdapter(templateType);
            }
        }
        return registerList;
    }

    private List<ModuleProject> addPasswordModuleSupport(Integer projectId, String templateType) {
        List<ModuleProject> registerList = moduleProjectService.queryByProjectAndModule(projectId, Contants.PASSWORD_MODULE);
        if (!registerList.isEmpty()) {
            for (ModuleProject mp : registerList) {
                //兼容ssh
                mp.frameAdapter(templateType);
            }
        }
        return registerList;
    }

    private List<ModuleProject> addQueryModuleSupport(Integer projectId, String templateType) {
        List<ModuleProject> queryList = moduleProjectService.queryByProjectAndModule(projectId, Contants.QUERY_MODULE);
        if (!queryList.isEmpty()) {
            for (ModuleProject mp : queryList) {
                //兼容ssh
                mp.frameAdapter(templateType);
                String query_url = null;
                //ssm
                if (templateType.equals(Contants.SSM_FRAME)) {
                    query_url = "<%=path %>/" + uncapFirst(mp.getTable().getClassName()) + "/list";
                }
                //ssh
                else if (templateType.equals(Contants.SSH_FRAME)) {
                    query_url = "<%=path %>/" + uncapFirst(mp.getTable().getClassName()) + "/" + uncapFirst(mp.getTable().getClassName()) + "-query.action";
                }
                //jsp
                else if (templateType.equals(Contants.JSP_FRAME)) {
                    query_url = "<%=path %>/query" + mp.getTable().getClassName() + "SelectedServlet";
                }
                //ssm custom
                else if (templateType.equals(Contants.SSM_CUSTOM_FRAME)) {
                    query_url = "<%=path %>/" + uncapFirst(mp.getTable().getClassName()) + "/list";
                }
                //ssm maven
                else if (templateType.equals(Contants.SSM_MAVEN_FRAME)) {
                    query_url = "<%=path %>/" + uncapFirst(mp.getTable().getClassName()) + "/list";
                }
                mp.setModuleUrl(query_url);
            }
        }
        return queryList;
    }


    private Map<String, Object> initMap(Table table, Map<String, Object> map, String templateType) {
        List<Colunm> colunmList = colunmMapper.queryByTable(table.getId());
        Colunm primary = colunmMapper.queryPrimaryKey(table.getId());
        //为了兼容ssh表单name显示不一致问题
        primary.frameAdapter(templateType);
        for (Colunm c : colunmList) {
            c.frameAdapter(templateType);
        }
        map.put("table", table);
        map.put("colunmList", colunmList);
        map.put("primary", primary);
        return map;
    }

}
