package xyz.wbsite.action.ajax.conf;

import freemarker.template.Template;
import freemarker.template.TemplateException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;
import xyz.wbsite.frame.auth.LocalData;
import xyz.wbsite.frame.base.ErrorType;
import xyz.wbsite.frame.base.SortType;
import xyz.wbsite.frame.utils.ProcessUtil;
import xyz.wbsite.module.conf.ent.Mapping;
import xyz.wbsite.module.conf.ent.NginxCtrl;
import xyz.wbsite.module.conf.mgr.MappingManager;
import xyz.wbsite.module.conf.req.MappingFindRequest;
import xyz.wbsite.module.conf.req.NginxReloadRequest;
import xyz.wbsite.module.conf.req.NginxStartRequest;
import xyz.wbsite.module.conf.req.NginxStopRequest;
import xyz.wbsite.module.conf.rsp.MappingFindResponse;
import xyz.wbsite.module.conf.rsp.NginxReloadResponse;
import xyz.wbsite.module.conf.rsp.NginxStartResponse;
import xyz.wbsite.module.conf.rsp.NginxStopResponse;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class NginxAjax {

    @Autowired
    private NginxCtrl nginxCtrl;
    @Autowired
    private MappingManager mappingManager;
    @Autowired
    private FreeMarkerConfigurer freeMarkerConfigurer;

    public NginxStartResponse start(NginxStartRequest request) {
        NginxStartResponse response = new NginxStartResponse();
        if (nginxCtrl.isRunning()) {
            response.addError(ErrorType.BUSINESS_ERROR, "程序已经运行");
            return response;
        }
        ProcessUtil.execBat(nginxCtrl.getStartCmd());
        return response;
    }

    public NginxStopResponse stop(NginxStopRequest request) {
        NginxStopResponse response = new NginxStopResponse();
        if (!nginxCtrl.isRunning()) {
            response.addError(ErrorType.BUSINESS_ERROR, "程序尚未运行");
            return response;
        }
        ProcessUtil.execBat(nginxCtrl.getStopCmd());
        return response;
    }

    public NginxReloadResponse reload(NginxReloadRequest request) {
        NginxReloadResponse response = new NginxReloadResponse();
        if (!nginxCtrl.isRunning()) {
            response.addError(ErrorType.BUSINESS_ERROR, "程序尚未运行");
            return response;
        }
        // 刷新配置文件
        flushConfig();
        // 重新加载配置文件
        ProcessUtil.execBat(nginxCtrl.getReloadCmd());
        return response;
    }

    public synchronized void flushConfig() {
        Writer wr = null;
        try {
            File config = nginxCtrl.getConfig();
            HashMap<String, Object> context = new HashMap<>();

            MappingFindRequest mappingFindRequest = new MappingFindRequest();
            mappingFindRequest.setPageSize(0);
            mappingFindRequest.setSortKey("PORT");
            mappingFindRequest.setSortType(SortType.ASC);
            MappingFindResponse mappingFindResponse = mappingManager.find(mappingFindRequest, LocalData.getSysToken());

            Map<String, List<Mapping>> services = new HashMap<>();

            for (Mapping mapping : mappingFindResponse.getResult()) {

                List<Mapping> mappings = services.get(mapping.getPort());

                if (mappings == null) {
                    mappings = new ArrayList<>();
                    services.put(mapping.getPort(), mappings);
                }
                mappings.add(mapping);
            }

            context.put("services", services);
            Template template = freeMarkerConfigurer.getConfiguration().getTemplate("nginx.conf.ftl");
            wr = new OutputStreamWriter(new FileOutputStream(config), "UTF-8");
            //写入
            template.process(context, wr);
            //关闭流
            wr.close();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (TemplateException e) {
            e.printStackTrace();
        } finally {
            try {
                wr.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
