package org.jeecg.modules.adweb.site.controller;


import com.alibaba.fastjson.JSONObject;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.modules.adweb.common.util.AdwebRedisUtil;
import org.jeecg.modules.adweb.site.entity.AdwebSite;
import org.jeecg.modules.adweb.site.service.IAdwebSiteService;
import org.jeecg.modules.adweb.site.service.SelfWebSiteService;
import org.jeecg.modules.adweb.site.service.SelfWebSiteServiceCommon;
import org.jeecg.modules.message.websocket.WebSocket;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * @autor jerry
 * @date: 2022/1/11 20:45
 */
@Slf4j
@RestController
@RequestMapping("/wpWebSite")
public class wpSiteController {

    @Value("${jeecg.path.upload}")
    private String uploadUrl;

    @Value("${pemFileDownLoad.prefix}")
    private String pemFileDownLoadUrl;

    @Resource
    private SelfWebSiteService selfWebSiteService;

    @Resource
    private IAdwebSiteService siteService;

    @Resource
    private SelfWebSiteServiceCommon selfWebSiteServiceCommon;

    @Resource
    private AdwebRedisUtil adwebRedisUtil;

    @Resource
    private WebSocket webSocket;

    /**
     * 创建站点
     *
     * @param templateId 模板id
     * @param planId     域名
     * @param name       站点名称
     * @param uid        站点所属用户名称
     * @param request    请求信息
     * @return 创建的站点信息
     */
    @RequestMapping("addWebsite")
    public Result<?> createWebSiteByTempId(HttpServletRequest request, Long templateId, String planId, String name, String uid, Integer giveDay, Integer compensateDay) {
        log.info("新建站点模板：" + templateId + "; 站点名称：" + name + "; 套餐id：" + planId);
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        // 如果2分钟内有创建过站点，则不允许再次创建站点
        String flag = adwebRedisUtil.getString(templateId + "_" + uid);
        if (StringUtils.isNotBlank(flag)) {
            log.info("2分钟内重复拉站点");
            try {
                Thread.sleep(5 * 60 * 1000);
            } catch (InterruptedException e) {
                log.info("重复拉站点的睡眠出现异常");
            }
            return Result.OK("ignore");
        }
        adwebRedisUtil.set(templateId + "_" + uid, "flag", 2 * 60);

        AdwebSite adwebSite = null;
        try {
            // 建站服务
            adwebSite = selfWebSiteService.createSite(request, templateId, uid, name, planId, sysUser, giveDay, compensateDay);
            if (null != adwebSite) {
                log.info("创建站点成功");
                //创建业务消息信息
                JSONObject obj = new JSONObject();
                obj.put("cmd", "user");//业务类型
                obj.put("msgId", "test");//消息id
                obj.put("msgTxt", "站点创建成功");//消息内容
                //单个用户发送 (userId为用户id)
                webSocket.sendMessage("e9ca23d68d884d4ebb19d07889727dae", obj.toJSONString());
                return Result.OK(adwebSite.getDomainDev());
            }
        } catch (Exception e) {
            log.error("创建站点失败", e);
        }
        return Result.error("创建站点失败！");
    }

    /**
     * 发布站点
     *
     * @param domain 域名
     * @param siteId 站点ID
     * @return
     */
    @RequestMapping("releaseWebsite")
    public Result<?> releaseWebsite(HttpServletRequest request, String domain, Integer siteId) {
        return selfWebSiteService.releaseSite(request, domain, siteId);
    }

    /**
     * 重新发布站点
     *
     * @param domain 域名
     * @param siteId 站点ID
     * @return
     */
    @RequestMapping("delReleaseWebsite")
    public Result<?> delReleaseWebsite(String domain, Integer siteId) {
        return selfWebSiteService.delReleaseWebsite(domain, siteId);
    }


    /**
     * 站点 启动/停止
     *
     * @param siteId 站点Id
     * @param status 站点启动（local）：1；停止：2; 站点启动（prod）：3；停止：4;
     * @return
     */
    @RequestMapping("siteStartOrStop")
    public Result<?> siteStartOrStop(Integer siteId, Integer status) {
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        boolean flag = selfWebSiteService.siteStartOrStop(sysUser, siteId, status);
        String result = "";
        if (flag) {
            if (status.equals(1) || status.equals(3)) {
                result = "站点启动成功！";
            }
            if (status.equals(2) || status.equals(4)) {
                result = "站点停止成功！";
            }
        } else {
            if (status.equals(1) || status.equals(3)) {
                result = "站点启动失败！";
            }
            if (status.equals(2) || status.equals(4)) {
                result = "站点停止失败！";
            }
        }
        return Result.OK(result);
    }


    /**
     * 手动添加SSL
     *
     * @param adwebSite
     * @return
     */
    @RequestMapping(value = "munualAddSSL", method = RequestMethod.POST)
    @ResponseBody
    public Result<?> munualAddSSL(AdwebSite adwebSite) {
        //开始校验证书格式是否正确
        String cert = adwebSite.getSiteCert();
        String chain = adwebSite.getSiteChain();
        String privateKey = adwebSite.getSitePrivkey();
        if (!cert.startsWith("-----BEGIN CERTIFICATE-----") || !cert.endsWith("-----END CERTIFICATE-----")
                || !chain.startsWith("-----BEGIN CERTIFICATE-----") || !chain.endsWith("-----END CERTIFICATE-----")
                || !privateKey.startsWith("-----BEGIN PRIVATE KEY-----") || !privateKey.endsWith("-----END PRIVATE KEY-----")) {
            return Result.error("ssl证书错误，请检查证书格式！");
        }
        String fullchain = cert.concat("\n").concat(chain);
        String uploadPemUrl = uploadUrl + "keys/";
        File newFile = new File(uploadPemUrl + adwebSite.getCode());
        if (!newFile.exists()) {
            newFile.mkdirs();
        }
        File file = new File(uploadPemUrl + adwebSite.getCode() + "/fullchain.pem");
        File file2 = new File(uploadPemUrl + adwebSite.getCode() + "/privkey.pem");
        try {
            FileOutputStream out = new FileOutputStream(file);
            FileOutputStream out2 = new FileOutputStream(file2);
            if (!file.exists()) {
                file.createNewFile();
            }
            if (!file2.exists()) {
                file2.createNewFile();
            }
            byte[] content = fullchain.getBytes();
            byte[] content2 = privateKey.getBytes();
            out.write(content);
            out2.write(content2);
            out.flush();
            out2.flush();
            out.close();
            out2.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        selfWebSiteService.munualAddSSL(adwebSite,
                pemFileDownLoadUrl + adwebSite.getCode() + "/fullchain.pem",
                pemFileDownLoadUrl + adwebSite.getCode() + "/privkey.pem");
        boolean flag = siteService.updateById(adwebSite);
        if (!flag) {
            return Result.error("添加失败");
        }
        return Result.OK();
    }


    /**
     * 自动添加SSL(脚本执行)
     *
     * @param adwebSite
     */
    @RequestMapping(value = "autoAddSsl")
    @ResponseBody
    public Result<?> autoAddSsl(AdwebSite adwebSite) {
        AdwebSite adwebSite1 = selfWebSiteService.autoAddSsl(adwebSite);
        if (StringUtils.isEmpty(adwebSite1.getSiteCert()) || StringUtils.isEmpty(adwebSite1.getSiteChain()) || StringUtils.isEmpty(adwebSite1.getSitePrivkey())) {
            return Result.error("证书添加失败！");
        }
        adwebSite1.setId(adwebSite.getId());
        return Result.OK(siteService.updateById(adwebSite1));
    }

    /**
     * 自动添加SSL
     *
     * @param adwebSite
     */
    @RequestMapping(value = "autoAddSsl/v2")
    @ResponseBody
    public Result<?> autoAddSslV2(AdwebSite adwebSite) {
        return selfWebSiteService.autoAddSslV2(adwebSite);
    }

}
