package com.example.demo.controller;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import com.example.demo.model.DbConfig;
import com.example.demo.util.CodeUtil;
import com.example.demo.util.ZipUtil;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.sql.*;
import java.util.*;

@RestController
@RequestMapping("/mydb")
public class DbController {

    @PostMapping("/connection")
    public List<String> connection(@RequestBody DbConfig dbConfig){
        List<String> tables = new ArrayList<>();
        String mysqlUrl = "jdbc:mysql://"+dbConfig.getMysqlIp()+":"+dbConfig.getMysqlPort()+"/"+dbConfig.getMysqlName()+"?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true";
        try {
            Connection con = DriverManager.getConnection(mysqlUrl,dbConfig.getMysqlUsername(),dbConfig.getMysqlUserpass());
//            DatabaseMetaData meta = con.getMetaData();
//            ResultSet rs = meta.getTables(null, dbConfig.getMysqlUsername(), null,
//                    new String[] { "TABLE" });
//            while (rs.next()) {
//                tables.add(rs.getString(3));
//            }
            String sql = "select table_name from information_schema.tables where table_schema='" + dbConfig.getMysqlName() + "'";
            Statement statement = con.createStatement();
            ResultSet result = statement.executeQuery(sql);
            while(result.next())
            {
                tables.add(result.getString("TABLE_NAME"));
            }
            con.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return tables;
    }

    @PostMapping("/create")
    public void create(@RequestBody DbConfig dbConfig, HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException {
//        String newFileName = "D:/" + UUID.randomUUID().toString().replaceAll("-", "") + "/" + "cj-demo";
        String newFileName = "/home/yansen/generator/temp/" + UUID.randomUUID().toString().replaceAll("-", "") + "/" + "cj-demo";
        dbConfig.getMysqlLib().forEach(e -> {
            AutoGeneratorFile(dbConfig,newFileName,e);
        });
        //设置响应头，控制浏览器下载该文件
        response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode("cj-demo" + ".zip", "UTF-8"));
        response.setCharacterEncoding("UTF-8");

        try {
            File file = new File(newFileName + ".zip");
            if (!file.exists()) {
                file.createNewFile();
            }
            FileOutputStream fous = new FileOutputStream(file);

            //压缩导出
            ZipUtil.toZip(newFileName, fous, true);
            response.setContentType("application/x-msdownload");
            //读取要下载的文件，保存到文件输入流
            FileInputStream in = new FileInputStream(file);
            //创建输出流
            OutputStream out = response.getOutputStream();
            //创建缓冲区
            byte[] buffer = new byte[1024];
            int len;
            //循环将输入流中的内容读取到缓冲区当中
            while ((len = in.read(buffer)) > 0) {
                //输出缓冲区的内容到浏览器，实现文件下载
                out.write(buffer, 0, len);
            }
            //关闭文件输入流
            in.close();
            //关闭输出流
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        String delFileName = newFileName.substring(0, newFileName.lastIndexOf("/"));
        //删除临时文件夹
        CodeUtil.delFolder(delFileName);
    }

    public void AutoGeneratorFile(DbConfig dbConfig, String newFileName,String tableName) {
        String mysqlUrl = "jdbc:mysql://"+dbConfig.getMysqlIp()+":"+dbConfig.getMysqlPort()+"/"+dbConfig.getMysqlName()+"?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true";
        // 代码生成器
        AutoGenerator mpg = new AutoGenerator();

        // 全局配置
        GlobalConfig gc = new GlobalConfig();
        gc.setOutputDir(newFileName);
        gc.setAuthor(StringUtils.isEmpty(dbConfig.getAuthor()) ? "cj" : dbConfig.getAuthor());
        gc.setOpen(false);
        mpg.setGlobalConfig(gc);

        // 数据源配置
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setUrl(mysqlUrl);
        dsc.setDriverName("com.mysql.cj.jdbc.Driver");
        dsc.setUsername(dbConfig.getMysqlUsername());
        dsc.setPassword(dbConfig.getMysqlUserpass());
        mpg.setDataSource(dsc);

        // 包配置
        PackageConfig pc = new PackageConfig();
//        pc.setModuleName("fxf");
        pc.setParent(dbConfig.getPackPath());
        mpg.setPackageInfo(pc);

        // 自定义配置
        InjectionConfig cfg = new InjectionConfig() {
            @Override
            public void initMap() {
                Map<String, Object> map = new HashMap<>();
                map.put("BasePackage", dbConfig.getPackPath());
                map.put("ResponseClassPackage", dbConfig.getPackPath() + ".common.ResponseBean");
                map.put("ResponseClass", "ResponseBean");
                this.setMap(map);
            }
        };

        // 如果模板引擎是 freemarker
        String templatePath = "/templates/mapper.xml.ftl";
        // 如果模板引擎是 velocity
        // String templatePath = "/templatesPlus/mapper.xml.vm";

        // 自定义输出配置
        List<FileOutConfig> focList = new ArrayList<>();
        // 自定义配置会被优先输出
        focList.add(new FileOutConfig(templatePath) {
            @Override
            public String outputFile(TableInfo tableInfo) {
                // 自定义输出文件名
                return newFileName + "/mapper/"
                        + "/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
            }
        });

        cfg.setFileOutConfigList(focList);
        mpg.setCfg(cfg);

        // 配置模板
        TemplateConfig templateConfig = new TemplateConfig();

        // 配置自定义输出模板
        // templateConfig.setEntity();
        // templateConfig.setService();
        templateConfig.setController("templatesPlus/controller.java");
        templateConfig.setMapper("templatesPlus/mapper.java");

        templateConfig.setXml(null);
        mpg.setTemplate(templateConfig);

        // 策略配置
        StrategyConfig strategy = new StrategyConfig();
        strategy.setNaming(NamingStrategy.underline_to_camel);
        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
        //strategy.setSuperEntityClass("com.baomidou.ant.common.BaseEntity");
        strategy.setEntityLombokModel(true);
        strategy.setRestControllerStyle(true);
        strategy.setSuperControllerClass(dbConfig.getPackPath() + ".common.BaseController");
        //表名
        strategy.setInclude(tableName);
        strategy.setSuperEntityColumns("id");
        strategy.setControllerMappingHyphenStyle(true);
        strategy.setTablePrefix(pc.getModuleName() + "_");
        mpg.setStrategy(strategy);
        mpg.setTemplateEngine(new FreemarkerTemplateEngine());
        mpg.execute();
    }

}
