package xyz.wbsite.dbtool.javafx.manger;

import freemarker.cache.ClassTemplateLoader;
import freemarker.cache.MultiTemplateLoader;
import freemarker.cache.TemplateLoader;
import freemarker.template.Configuration;
import freemarker.template.DefaultListAdapter;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.TemplateExceptionHandler;
import freemarker.template.TemplateMethodModelEx;
import freemarker.template.TemplateModelException;
import org.springframework.util.ClassUtils;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;
import xyz.wbsite.dbtool.javafx.po.SelectItem;
import xyz.wbsite.dbtool.javafx.tool.Tool;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.Iterator;
import java.util.List;

public class FreeMarkerManager {
    private FreeMarkerConfigurer freeMarkerConfigurer;

    public FreeMarkerManager() {
        freeMarkerConfigurer = new FreeMarkerConfigurer();
        // 初始化一些配置
        Configuration cfg = new Configuration(Configuration.VERSION_2_3_28);
        cfg.setDefaultEncoding("UTF-8");
        cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
        cfg.setNumberFormat("0.##");
        cfg.setSharedVariable("print", new Print());
        cfg.setSharedVariable("uuid", new Uuid());
        cfg.setSharedVariable("toString", new ToString());

        MultiTemplateLoader multiTemplateLoader = new MultiTemplateLoader(new TemplateLoader[]{
                new ClassTemplateLoader(ClassUtils.getDefaultClassLoader(), "/modules"),
        });

        cfg.setTemplateLoader(multiTemplateLoader);
        freeMarkerConfigurer.setConfiguration(cfg);
    }

    public void outputTemp(File outfile, String template, Object model) {
        try {
            if (!outfile.exists()) {
                outfile.createNewFile();
            }

            //获取连接
            Configuration configuration = freeMarkerConfigurer.getConfiguration();
            //设置编码
            configuration.setDefaultEncoding("UTF-8");
            //获取ftl,由于已经在配置文件中配置了路径所以在这里直接写模板名称就可以
            Template temp = configuration.getTemplate(template);
            //输出文件路径
            Writer wr = new OutputStreamWriter(new FileOutputStream(outfile), "UTF-8");
            //写入
            temp.process(model, wr);
            //关闭流
            wr.close();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (TemplateException e) {
            e.printStackTrace();
        }
    }

    private class Print implements TemplateMethodModelEx {

        @Override
        public Object exec(List list) throws TemplateModelException {
            if (list.size() == 1) {
                return list.get(0);
            } else if (list.size() > 1) {
                return String.join(",", list);
            }
            return "";
        }
    }

    private class Uuid implements TemplateMethodModelEx {

        @Override
        public Object exec(List list) throws TemplateModelException {
            return Tool.uuid();
        }
    }

    private class ToString implements TemplateMethodModelEx {

        @Override
        public Object exec(List list) throws TemplateModelException {

            if (list.size() > 0) {
                DefaultListAdapter list1 = (DefaultListAdapter) list.get(0);
                List wrappedObject = (List) list1.getWrappedObject();
                if (wrappedObject.get(0) instanceof SelectItem) {
                    StringBuffer sb = new StringBuffer("{");

                    Iterator iterator = wrappedObject.iterator();
                    while (iterator.hasNext()) {
                        SelectItem next = (SelectItem) iterator.next();
                        sb.append("\"");
                        sb.append(next.getValue());
                        sb.append("\"");
                        if (iterator.hasNext()) {
                            sb.append(", ");
                        }
                    }
                    sb.append("}");
                    return sb.toString();
                }
            }

            return "";
        }
    }

}
