package com.cm.common.util;

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

import com.cm.common.config.properties.SystemProperties;
import com.cm.common.pojo.dtos.templateconfig.TemplateConfigDTO;
import com.cm.common.pojo.vos.templaterecord.TemplateRecordVO;
import com.cm.common.service.templaterecord.ITemplateRecordService;
import com.cm.common.utils.DateUtil;
import freemarker.cache.StringTemplateLoader;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateExceptionHandler;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PostAuthorize;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;

/**
 * 生成静态模板文件工具类
 */
@Component
public class TemplateBuilderUtil {

    private static TemplateBuilderUtil templateUtil = TemplateUtilBuilder.templateUtil;

    @Autowired
    private SystemProperties systemProperties;

    private static SystemProperties  systemStitacProperties;

    @Autowired
    private FreemarkerTemplateProperties freemarkerTemplateProperties;

    private static FreemarkerTemplateProperties  freemarkerTemplateStaticProperties;


    /**
     * 模板文件控制器
     */
    private static Configuration cfg;

    @Autowired
    private ITemplateRecordService iTemplateRecordService;

    private static ITemplateRecordService  iTemplateRecordStaticService;

    @PostConstruct
    public void init() {
        iTemplateRecordStaticService = this.iTemplateRecordService;
        systemStitacProperties =  this.systemProperties;
        freemarkerTemplateStaticProperties = this.freemarkerTemplateProperties;
    }

    /**
     * 所有模板文件的存储
     */
    private static Map<String, TemplateConfigDTO> templateMap = new HashMap<String, TemplateConfigDTO>();

    static {
        cfg = new Configuration(Configuration.VERSION_2_3_23);
        try {
            // 设置默认编码
            cfg.setDefaultEncoding("UTF-8");
            // 错误信息输出到控制台
            cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 模板加入和更新
     * @param templateCode 模板编码
     */
    public void removeTemplate(String templateCode) {
        templateMap.remove(templateCode);
    }

    /**
     * 模板加入和更新
     * @param templateCode 模板编码
     * @param templateConfigDTO 模板对象
     */
    public void pushTemplate(String templateCode, TemplateConfigDTO templateConfigDTO) {
        StringTemplateLoader stringTemplateLoader = new StringTemplateLoader();
        stringTemplateLoader.putTemplate(templateCode, templateConfigDTO.getTemplateContent());
        templateConfigDTO.setStringTemplateLoader(stringTemplateLoader);
        templateMap.put(templateCode, templateConfigDTO);
    }

    /**
     *  静态模板文件生成
     * @throws Exception
     */
    public TemplateRecordVO createFile(TemplateCreateData templateCreateData) throws Exception {
        TemplateConfigDTO templateConfigDTO = templateMap.get(templateCreateData.getTemplateCode());
        if (templateConfigDTO == null || templateConfigDTO.getStringTemplateLoader() == null) {
            throw new Exception("该模板不存在");
        }
        if(StringUtils.isEmpty(templateCreateData.getBusinessId())) {
            throw new Exception("业务ID不能为空");
        }
        // 2020年10月27日16:07:50 崔宝铖
        templateCreateData.getTemplateDataMap().put("SYSTEM_URL", systemStitacProperties.getUrl());
        templateCreateData.getTemplateDataMap().put("SYSTEM_TITLE", systemStitacProperties.getTitle());
        templateCreateData.getTemplateDataMap().put("SYSTEM_PORT", systemStitacProperties.getPort());
        templateCreateData.getTemplateDataMap().put("NGINX_URL", freemarkerTemplateStaticProperties == null ? "" : freemarkerTemplateStaticProperties.getNginxAddress());

        // 创建模板存储文件夹
        String outFilePath = StringUtils.isEmpty(templateCreateData.getOutFilePath()) ? (DateUtil.getYear() + File.separator + DateUtil.getMonth() + File.separator + DateUtil.getToday() + File.separator ) : templateCreateData.getOutFilePath();
        String outFileName = StringUtils.isEmpty(templateCreateData.getOutFileName()) ? templateCreateData.getBusinessId() + ".html" : templateCreateData.getOutFileName();

        cfg.setTemplateLoader(templateConfigDTO.getStringTemplateLoader());
        Template temp = cfg.getTemplate(templateCreateData.getTemplateCode(),"utf-8");
        File file = new File(templateConfigDTO.getTemplateRootPath() + outFilePath);
        if(!file.exists()) {
            file.mkdirs();
        }
        // 输出模板结果文件
        String fileName = templateConfigDTO.getTemplateRootPath() + outFilePath + outFileName;
        File saveFile = new File(fileName);
        // 如果文件已经存在则删除
        if(saveFile.exists()) {
            saveFile.delete();
        }
        Writer out = new FileWriter(saveFile);
        temp.process(templateCreateData.getTemplateDataMap(), out);
        out.flush();
        /**
         * 做生成模板记录
         */
        TemplateRecordVO recordVo = new TemplateRecordVO();
        recordVo.setBusinessContent(templateCreateData.getBusinessContent());
        recordVo.setTemplateRecordId(templateCreateData.getBusinessId());
        recordVo.setTemplateId(templateConfigDTO.getTemplateConfigId());
        recordVo.setTemplateRecordBuilderTime(DateUtil.getTime());
        recordVo.setTemplateRecordPath(fileName);
        recordVo.setTemplateRecordUrl(outFilePath.replaceAll("\\\\", "/") + outFileName);
        iTemplateRecordStaticService.saveTemplateRecord(recordVo);
        return recordVo;
    }

    public static void main(String[] args) throws Exception {
        Map<String,Object> root = new HashMap<String,Object>();
        root.put("action"  ,"deny"  );
        root.put("protocol" ,"udp"  );
        root.put("source_ip_address"  ,"192.168.56.123"  );
        root.put("source_wildcard"  ,"0.0.0.255"  );
        root.put("destination_ip_address"  ,"192.168.56.123"  );
        root.put("destination_wildcard"  ,"0.0.0.255"  );
        root.put("operator"  ,"gt"  );
        root.put("destination_port"  ,"128"  );
    }

    private TemplateBuilderUtil() {}


    public static TemplateBuilderUtil getInstance() {
        return templateUtil;
    }

    private static class TemplateUtilBuilder {
        public static final TemplateBuilderUtil templateUtil = new TemplateBuilderUtil();
    }

}
