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

import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.UUIDGenerator;
import org.jeecg.modules.adweb.common.constant.ShellConstans;
import org.jeecg.modules.adweb.common.service.FeishuService;
import org.jeecg.modules.adweb.common.service.ShellService;
import org.jeecg.modules.adweb.common.util.ShellSSH2Util;
import org.jeecg.modules.adweb.site.constant.WordPressConstants;
import org.jeecg.modules.adweb.site.entity.AdwebSite;
import org.jeecg.modules.system.mapper.SysDictItemMapper;
import org.jeecg.modules.system.mapper.SysDictMapper;
import org.jeecg.modules.system.service.ISysDictService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @author jerry
 */
@Slf4j
@Service
public class SelfWebSiteService {

    @Resource
    private IAdwebSiteService siteService;

    /**
     * 远程脚本执行服务类
     */
    @Resource
    private ShellService shellService;


    @Resource
    private SelfWebSiteServiceCommon selfWebSiteServiceCommon;


    @Value(value = "${jeecg.minio.dataPrefix}")
    private String dataPrefix;

    @Value(value = "${jeecg.minio_us.dataPrefix}")
    private String usDataPrefix;

    @Value("${AdwebSiteConnect.host}")
    private String host;
    @Value("${AdwebSiteConnect.port}")
    private int port;
    @Value("${AdwebSiteConnect.username}")
    private String username;
    @Value("${AdwebSiteConnect.password}")
    private String password;
    @Value("${AdwebSiteConnect.tempDomain}")
    private String tempDomain;
    @Value("${AdwebSiteConnect.tempCname}")
    private String tempCname;
    @Value("${AdwebSiteProdConnect.privateIp}")
    private String wpSiteReleasePrivateIp;
    @Value("${usWest118Server.shellpath}")
    private String usWest118ServerShellPath;
    @Resource
    private FeishuService openFeishuMsgService;

    @Autowired
    private ISysDictService dictService;

    @Resource
    private SysDictItemMapper sysDictItemMapper;

    @Resource
    private SysDictMapper sysDictMapper;

    /**
     * @param tempId 模板ID
     * @param uid    系统用户信息
     * @param name   站点名称
     * @param planId 新建站点绑定的套餐
     * @return
     */
    public AdwebSite createSite(HttpServletRequest request, Long tempId, String uid, String name, String planId, LoginUser sysUser, Integer giveDay, Integer compensateDay) {
        // 创建站点信息，生成code，拼接域名等，并将站点信息写入数据库

        AdwebSite adwebSite = null;
        try {
            adwebSite = selfWebSiteServiceCommon.saveNewSiteInfo(tempId, uid, name, planId, sysUser, giveDay, compensateDay);
            if (adwebSite == null) {
                return null;
            }
        } catch (Exception e) {
            log.error("新建站点时保存站点信息失败", e);
            return null;
        }

        try {
            if (request != null) {
                HttpSession session = request.getSession();
                session.setAttribute("shellLineModular", "");
            }

            // 执行临时服务器shell脚本，生成临时站点
            String cmd = "/opt/adweb3/shell/auto-website " + adwebSite.getCode() + " " + adwebSite.getParentCode();

            shellService.createShareSiteByPwd(cmd, host, port, username, password, new ShellSSH2Util.StdoutListener() {
                @Override
                public void stdout(String line) {
                    log.info("标准 ：{}", line);
                    if (request != null) {
                        msgSetInSession(request, line);
                    }
                    if (line.startsWith("执行命令成功")) {
                        log.info("站点创建成功！更新站点状态");
                    }
                }

                @Override
                public void stderr(String line) {
                    log.info("错误 ：{}", line);
                }
            });
        } catch (Exception e) {
            log.error("在wp服务器上生成站点文件失败");
            adwebSite.setStatus(0);
            siteService.updateById(adwebSite);
            return null;
        }
        return adwebSite;
    }

    private void msgSetInSession(HttpServletRequest request, String line) {
        HttpSession session = request.getSession();
        if ("CP_TAR_GZ_START".equals(line)) {
            session.setAttribute("testSiteProcess", "CP_TAR_GZ");
        }
        if ("SQL_DUMP_IMPORT_START".equals(line)) {
            session.setAttribute("testSiteProcess", "SQL_DUMP_IMPORT");
        }
        if ("WP_UDONM_START".equals(line)) {
            session.setAttribute("testSiteProcess", "WP_UDONM");
        }
        if ("WP_UDONM_END".equals(line)) {
            session.setAttribute("testSiteProcess", "SUCCESS");
        }
    }

    private void msgSetInSessionProd(HttpServletRequest request, String line) {
        HttpSession session = request.getSession();
        if ("wget_tar_start".equals(line)) {
            session.setAttribute("prodSiteProcess", "wget_tar_start");
        }
        if ("wget_sql_start".equals(line)) {
            session.setAttribute("prodSiteProcess", "wget_sql_start");
        }
        if ("start tar zxf".equals(line)) {
            session.setAttribute("prodSiteProcess", "start tar zxf");
        }
        if ("wp_udomain_start".equals(line)) {
            session.setAttribute("prodSiteProcess", "wp_udomain_start");
        }
        if ("wp_udomain_end".equals(line)) {
            session.setAttribute("prodSiteProcess", "success");
        }
    }


    /**
     * 站点启动/停止
     *
     * @param sysUser
     * @param siteId
     * @param status
     * @return
     */
    public boolean siteStartOrStop(LoginUser sysUser, Integer siteId, Integer status) {
        AdwebSite adwebSite = siteService.getById(siteId);
        boolean flag = false;
        switch (status) {
            case 1:
                flag = startSiteLocal(sysUser, adwebSite);
                break;
            case 2:
                flag = stopSiteLocal(sysUser, adwebSite);
                break;
            case 3:
                flag = startSite(sysUser, adwebSite);
                break;
            case 4:
                flag = stopSite(sysUser, adwebSite);
                break;
        }
        return flag;
    }

    /**
     * 站点启动脚本调用(未发布)
     *
     * @param sysUser
     * @param adwebSite
     * @return
     */
    private boolean startSiteLocal(LoginUser sysUser, AdwebSite adwebSite) {
        //站点启动
        String cmd = "/home/ci-user/shell/start_site " + adwebSite.getCode() + " ";
        shellService.exceShellByPwd(cmd, host, port, username, password, new ShellSSH2Util.StdoutListener() {
            @Override
            public void stdout(String line) {
                log.info("标准 ：" + line);
                if ("ERROR:FILE_NAME IS EXISTS".equals(line)) {
                    // TODO ----
                    log.error("恢复测试站点异常：" + line);
                }
            }

            @Override
            public void stderr(String line) {
                log.info("错误 ：" + line);
            }
        });
        return siteStatusUpdate(sysUser, adwebSite, 0);
    }

    /**
     * 站点停止脚本调用（未发布）
     *
     * @param sysUser
     * @param adwebSite
     * @return
     */
    private boolean stopSiteLocal(LoginUser sysUser, AdwebSite adwebSite) {
        String cmd = "/home/ci-user/shell/stop_site " + adwebSite.getCode() + " ";
        shellService.exceShellByPwd(cmd, host, port, username, password, new ShellSSH2Util.StdoutListener() {
            @Override
            public void stdout(String line) {
                log.info("标准 ：" + line);
                if ("ERROR:FILE_NAME IS EXISTS".equals(line)) {
                    // TODO ----
                    log.error("停止测试站点异常：" + line);
                }
            }

            @Override
            public void stderr(String line) {
                log.info("错误 ：" + line);
            }
        });
        return siteStatusUpdate(sysUser, adwebSite, 3);
    }

    /**
     * 站点启动脚本调用(生产环境)
     *
     * @param sysUser
     * @param adwebSite
     * @return
     */
    private boolean startSite(LoginUser sysUser, AdwebSite adwebSite) {
        //站点启动
        String cmd = "./shell/start_site " + wpSiteReleasePrivateIp + " " + adwebSite.getCode() + " ";
        shellService.exceShell(cmd, new ShellSSH2Util.StdoutListener() {
            @Override
            public void stdout(String line) {
                log.info("MJJ控制台 ：" + line);
                if ("ERROR:FILE_NAME IS EXISTS".equals(line)) {
                    // TODO ----
                    log.error("恢复站点异常：" + line);
                }
            }

            @Override
            public void stderr(String line) {
                log.info("错误 ：" + line);
            }
        });
        return siteStatusUpdate(sysUser, adwebSite, 0);
    }

    /**
     * 站点停止脚本调用（生产环境）
     *
     * @param sysUser
     * @param adwebSite
     * @return
     */
    private boolean stopSite(LoginUser sysUser, AdwebSite adwebSite) {
        String cmd = "./shell/stop_site " + wpSiteReleasePrivateIp + " " + adwebSite.getCode() + " ";
        shellService.exceShell(cmd, new ShellSSH2Util.StdoutListener() {
            @Override
            public void stdout(String line) {
                log.info("MJJ控制台 ：" + line);
                if ("ERROR:FILE_NAME IS EXISTS".equals(line)) {
                    // TODO ----
                    log.error("停止站点异常：" + line);
                }
            }

            @Override
            public void stderr(String line) {
                log.info("错误 ：" + line);
            }
        });
        return siteStatusUpdate(sysUser, adwebSite, 3);
    }


    /**
     * 站点状态更改
     *
     * @param sysUser
     * @param adwebSite
     * @param runStatus
     * @return
     */
    private boolean siteStatusUpdate(LoginUser sysUser, AdwebSite adwebSite, Integer runStatus) {
        if (runStatus.equals(3)) {
            adwebSite.setStopTime(new Date());
            adwebSite.setStopUid(sysUser.getId());
        }
        adwebSite.setRunStatus(runStatus);
        return siteService.updateById(adwebSite);
    }


    /**
     * 发布站点(生产环境)
     *
     * @param domain 新域名
     * @param siteId 站点ID
     */
    public Result<?> releaseSite(HttpServletRequest request, String domain, Integer siteId) {
        log.info("===== releaseSite domain:{},siteId:{} ====", domain, siteId);
        StringBuilder statusSuccess = new StringBuilder();
        StringBuilder statusFail = new StringBuilder();
        AdwebSite adwebSite = siteService.getById(siteId);
        String siteToken = UUIDGenerator.generate().toUpperCase();
        HttpSession session = request.getSession();
//        String cmd = " ./shell/auto_website " + wpSiteReleasePrivateIp + " " + adwebSite.getCode() + " " + adwebSite.getInCode() + " " + domain + " " + siteToken + " " + tempDomain;
        if (StringUtils.isEmpty(adwebSite.getDevServerIp())) {
            return Result.error("该站点的服务器IP没有设置，请设置后在发布上线！");
        }
        log.info("===== releaseSite domain:{},siteId:{},getDevServerIp:{} ====", domain, siteId, adwebSite.getDevServerIp());
        if ((!WordPressConstants.DEV_CI1.equals(adwebSite.getDevServerIp())) && (!WordPressConstants.DEV_CI2.equals(adwebSite.getDevServerIp()))) {
            return Result.error("该站点的服务器IP设置不正确，请重试！");
        }

        //原始域名
        String originDomain = domain;
        //检验域名是否以www开头
        if (domain.startsWith("www.")) {
            domain = domain.replace("www.", "");
        }
        String dbName = domain.replaceAll("[^a-zA-Z0-9]", "") + "_" + adwebSite.getCode();
        log.info("===== releaseSite domain:{},siteId:{},originDomain:{},domain:{},dbName:{} ====", domain, siteId, originDomain, domain, dbName);

        String cmd = "";
        if (WordPressConstants.DEV_CI1.equals(adwebSite.getDevServerIp())) {
            cmd = "sudo sh " + usWest118ServerShellPath + "/adweb-publish_http.sh " + adwebSite.getCode() + " " + domain + " " + dbName;
        }
        if (WordPressConstants.DEV_CI2.equals(adwebSite.getDevServerIp())) {
            cmd = "sudo sh " + usWest118ServerShellPath + "/adweb-publish-devci2_http.sh " + adwebSite.getCode() + " " + domain + " " + dbName;
        }
        log.info("===== releaseSite originDomain:{},domain:{},siteId:{},cmd:{} ====", originDomain, domain, siteId, cmd);

        if (StringUtils.isEmpty(cmd)) {
            String errorMsg = "网站上线脚本命令获取失败！";
            String title = "网站域名：" + originDomain + " 站点发布失败";
            String message = "**站点ID:** " + siteId + "\n";
            message += "**临时域名:** " + adwebSite.getDomainDev() + "\n";
            message += "**服务器IP:** " + adwebSite.getDevServerIp() + "\n";
            message += "**错误原因:** " + errorMsg + "\n";
            sendAdWebV2FeiShuMsg(title, message);
            return Result.error("该站点的发布上线命令执行失败，请重试！");
        }

//        return false;
        try {
//            modifyMaterialImgToUs(adwebSite.getCode());
            shellService.exceShellByUsWest118(cmd, new ShellSSH2Util.StdoutListener() {
                @Override
                public void stdout(String line) {
                    log.info("标准 ：" + line);
                    msgSetInSessionProd(request, line);
                    if ("ERROR:FILE_NAME IS EXISTS".equals(line)) {
                        // TODO ----
                    }
                    if ("[Creationcompleted]".equals(line)) {
                        log.info("======网站上线成功======");
                        statusSuccess.append("ok");
                    }
                }

                @Override
                public void stderr(String line) {
                    log.info("错误 ：" + line);
                    statusFail.append(line);
                }
            });
//            //发布完成后，调用脚本，停止测试站点的访问
//            try {
//                String delCmd = "/home/ci-user/shell/deldns " + adwebSite.getCode();
//                log.info("/***************开始停止测试站点*****************/");
//                shellService.createShareSiteByPwd(delCmd, host, port, username, password, new ShellSSH2Util.StdoutListener() {
//                    @Override
//                    public void stdout(String line) {
//                        log.info("停止测试站,标准 ：" + line);
//                        //信息存入session
//                        if ("ERROR:FILE_NAME IS EXISTS".equals(line)) {
//                            // TODO ----
//                        }
//                    }
//
//                    @Override
//                    public void stderr(String line) {
//                        log.info(line);
//                    }
//                });
//                log.info("/***************停止测试站点结束，成功*****************/");
//            } catch (Exception e) {
//                log.info("停止测试站异常", e);
//                e.printStackTrace();
//            }
            //正式域名

            log.info("===== releaseSite originDomain:{},domain:{},siteId:{},statusSuccess:{} ====", originDomain, domain, siteId, statusSuccess);
            log.info("===== releaseSite originDomain:{},domain:{},siteId:{},statusFail:{} ====", originDomain, domain, siteId, statusFail);
            if (StringUtils.isNotEmpty(statusFail.toString())) {
                String title = "网站域名：" + originDomain + " 站点发布失败";
                String message = "**站点ID:** " + siteId + "\n";
                message += "**临时域名:** " + adwebSite.getDomainDev() + "\n";
                message += "**服务器IP:** " + adwebSite.getDevServerIp() + "\n";
                message += "**错误信息:** " + statusFail.toString() + "\n";
                sendAdWebV2FeiShuMsg(title, message);

                // 站点发布失败
                adwebSite.setStatus(5);
                siteService.updateById(adwebSite);
                return Result.error("网站发布上线失败！");
            } else {
                String title = "网站域名：" + originDomain + " 站点发布成功";
                String message = "**站点ID:** " + siteId + "\n";
                message += "**临时域名:** " + adwebSite.getDomainDev() + "\n";
                message += "**服务器IP:** " + adwebSite.getDevServerIp() + "\n";
                sendAdWebV2FeiShuMsg(title, message);

                // 创建站点完成-操作
                adwebSite.setDomain(originDomain);
                adwebSite.setIsDomain(1);
                adwebSite.setSiteType(2);
                //添加发布时间
                adwebSite.setIssueTime(new Date());
                //发布成功后修改状态为发布成功状态 ：1
                adwebSite.setStatus(1);
                adwebSite.setProdServerIp(WordPressConstants.PROD_WP_SERVER_IP);
                siteService.updateById(adwebSite);
                // 将数据库中关键词的域名修改一致
                // UpdateWrapper<SeoKeywords> updateWrapper = new UpdateWrapper<>();
                // updateWrapper.eq("user_flag", adwebSite.getCode());
                // updateWrapper.set("domain", domain);
                // seoKeywordsService.update(updateWrapper);
                session.setAttribute("shellLineModular", "");
                return Result.OK("网站发布上线成功！");
            }
        } catch (Exception e) {
            log.error("站点发布失败，退出执行；" + e.getMessage(), e);
            // 站点发布失败
            adwebSite.setStatus(5);
            siteService.updateById(adwebSite);
            return Result.error("网站发布上线失败！");
        }
    }

    /**
     * 删除发布失败的站点(生产环境)
     *
     * @param domain 新域名
     * @param siteId 站点ID
     */
    public Result<?> delReleaseWebsite(String domain, Integer siteId) {
        log.info("===== delReleaseWebsite domain:{},siteId:{} ====", domain, siteId);
        StringBuilder delSuccess = new StringBuilder();
        StringBuilder delFail = new StringBuilder();
        AdwebSite adwebSite = siteService.getById(siteId);
        //检验域名是否以www开头
        if (domain.startsWith("www.")) {
            domain = domain.replace("www.", "");
        }
        // 删除已发布的站点，重新发布
        if (adwebSite.getStatus() == 5) {
            String cmd = "sudo sh " + usWest118ServerShellPath + "/adweb-remove_prod_site.sh " + domain;
            log.info("===== delReleaseWebsite domain:{},siteId:{},cmd:{} ====", domain, siteId, cmd);
            try {
                String finalDomain = domain;
                shellService.exceShellByUsWest118(cmd, new ShellSSH2Util.StdoutListener() {
                    @Override
                    public void stdout(String line) {
                        log.info("标准 ：" + line);
                        if ("remove site success".equals(line) || "remove site nginx success".equals(line)) {
                            log.info("======执行删除旧站点，成功通知======");
                            String title = "网站域名：" + finalDomain + " 删除发布失败的旧站点成功";
                            String message = "**站点ID:** " + siteId + "\n";
                            message += "**临时域名:** " + adwebSite.getDomainDev() + "\n";
                            message += "**服务器IP:** " + adwebSite.getDevServerIp() + "\n";
                            sendAdWebV2FeiShuMsg(title, message);

                            delSuccess.append(line);
                        }

                        if ("remove site failed".equals(line) || "remove site nginx failed".equals(line)) {
                            log.info("======执行删除旧站点，失败通知======");
                            String title = "网站域名：" + finalDomain + " 删除发布失败的旧站点失败";
                            String message = "**站点ID:** " + siteId + "\n";
                            message += "**临时域名:** " + adwebSite.getDomainDev() + "\n";
                            message += "**服务器IP:** " + adwebSite.getDevServerIp() + "\n";
                            message += "**错误信息:** " + line + "\n";
                            sendAdWebV2FeiShuMsg(title, message);

                            delFail.append(line);
                        }
                    }

                    @Override
                    public void stderr(String line) {
                        log.info("错误 ：" + line);
                        String title = "网站域名：" + finalDomain + " 删除发布失败的旧站点失败";
                        String message = "**站点ID:** " + siteId + "\n";
                        message += "**临时域名:** " + adwebSite.getDomainDev() + "\n";
                        message += "**服务器IP:** " + adwebSite.getDevServerIp() + "\n";
                        message += "**错误信息:** " + line + "\n";
                        sendAdWebV2FeiShuMsg(title, message);

                        delFail.append(line);
                    }
                });
            } catch (Exception e) {
                log.error("删除发布失败的旧站点失败，退出执行；" + e.getMessage(), e);
                delFail.append(e.getMessage());
            }

            if (StringUtils.isNotBlank(delFail.toString())) {
                return Result.error("旧站点删除失败，请重试！");
            } else {
                return Result.OK("旧站点删除成功！");
            }
        } else {
            return Result.error("该站点状态不是发布失败，执行失败！");
        }
    }


    /**
     * 自动添加SSL(脚本执行)
     *
     * @param adwebSite
     */
    public AdwebSite autoAddSsl(AdwebSite adwebSite) {
        String cmd;
        StringBuilder isExists = new StringBuilder();
        StringBuilder notExists = new StringBuilder();
        cmd = "./shell/read_cert " + wpSiteReleasePrivateIp + " " + adwebSite.getDomain();
        shellService.exceShell(cmd, new ShellSSH2Util.StdoutListener() {
            @Override
            public void stdout(String line) {
                log.info("控制台：" + line);
                //存在
                if (line.startsWith(ShellConstans.addSsl.IS_ERROR_INFO)) {
                    isExists.append(line);
                }
                //不存在
                if (line.startsWith(ShellConstans.addSsl.NULL_ERROR_INFO)) {
                    notExists.append(line);
                }
            }

            @Override
            public void stderr(String line) {
                log.info("错误：" + line);
            }
        });

        if (StringUtils.isNotBlank(isExists.toString())) {
            StringBuilder privekeySb = new StringBuilder();
            StringBuilder cert = new StringBuilder();
            StringBuilder chain = new StringBuilder();
            StringBuilder dataTime = new StringBuilder();
            final Map<String, Boolean> certWriteMap = new HashMap<>();
            certWriteMap.put("isCertWrite", false);
            certWriteMap.put("isPrivateKeyWrite", false);
            certWriteMap.put("isChainWrite", false);
            cmd = "./shell/update_cert " + wpSiteReleasePrivateIp + " " + adwebSite.getDomain();
            shellService.exceShell(cmd, new ShellSSH2Util.StdoutListener() {
                @Override
                public void stdout(String line) {
                    log.info("控制台：" + line);
                    if (line.startsWith(ShellConstans.addSsl.DATE_TIME)) {
                        dataTime.append(line);
                    }
                    //cert
                    if (line.startsWith(ShellConstans.addSsl.START_CERT)) {
                        certWriteMap.put("isCertWrite", true);
                    } else if (line.startsWith(ShellConstans.addSsl.END_CERT)) {
                        certWriteMap.put("isCertWrite", false);
                    }
                    // 私有key可写
                    if (certWriteMap.get("isCertWrite") && !line.startsWith(ShellConstans.addSsl.START_CERT)) {
                        cert.append(line);
                        cert.append('\n');
                    }
                    //privkey
                    if (line.startsWith(ShellConstans.addSsl.START_PRIVKEY)) {
                        certWriteMap.put("isPrivateKeyWrite", true);
                    } else if (line.startsWith(ShellConstans.addSsl.END_PRIVKEY)) {
                        certWriteMap.put("isPrivateKeyWrite", false);
                    }
                    // 私有key可写
                    if (certWriteMap.get("isPrivateKeyWrite") && !line.startsWith(ShellConstans.addSsl.START_PRIVKEY)) {
                        privekeySb.append(line);
                        privekeySb.append('\n');
                    }
                    //chain
                    if (line.startsWith(ShellConstans.addSsl.START_CHAIN)) {
                        certWriteMap.put("isChainWrite", true);
                    } else if (line.startsWith(ShellConstans.addSsl.END_CHAIN)) {
                        certWriteMap.put("isChainWrite", false);
                    }
                    // 私有key可写
                    if (certWriteMap.get("isChainWrite") && !line.startsWith(ShellConstans.addSsl.START_CHAIN)) {
                        chain.append(line);
                        chain.append('\n');
                    }
                }

                @Override
                public void stderr(String line) {
                    log.info("错误：" + line);
                }
            });
            adwebSite.setSiteCert(cert.toString());
            adwebSite.setSiteChain(chain.toString());
            adwebSite.setSitePrivkey(privekeySb.toString());
        } else if (StringUtils.isNotBlank(notExists.toString())) {
            StringBuilder privekeySb = new StringBuilder();
            StringBuilder cert = new StringBuilder();
            StringBuilder chain = new StringBuilder();
            StringBuilder dataTime = new StringBuilder();
            final Map<String, Boolean> certWriteMap = new HashMap<>();
            certWriteMap.put("isCertWrite", false);
            certWriteMap.put("isPrivateKeyWrite", false);
            certWriteMap.put("isChainWrite", false);
            cmd = "./shell/make_cert " + wpSiteReleasePrivateIp + " " + adwebSite.getCode() + " " + adwebSite.getInCode() + " " + adwebSite.getDomain();
            shellService.exceShell(cmd, new ShellSSH2Util.StdoutListener() {
                @Override
                public void stdout(String line) {
                    log.info("控制台：" + line);
                    if (line.startsWith(ShellConstans.addSsl.DATE_TIME)) {
                        dataTime.append(line);
                    }
                    //cert
                    if (line.startsWith(ShellConstans.addSsl.START_CERT)) {
                        certWriteMap.put("isCertWrite", true);
                    } else if (line.startsWith(ShellConstans.addSsl.END_CERT)) {
                        certWriteMap.put("isCertWrite", false);
                    }
                    // 私有key可写
                    if (certWriteMap.get("isCertWrite") && !line.startsWith(ShellConstans.addSsl.START_CERT)) {
                        cert.append(line);
                        cert.append('\n');
                    }
                    //privkey
                    if (line.startsWith(ShellConstans.addSsl.START_PRIVKEY)) {
                        certWriteMap.put("isPrivateKeyWrite", true);
                    } else if (line.startsWith(ShellConstans.addSsl.END_PRIVKEY)) {
                        certWriteMap.put("isPrivateKeyWrite", false);
                    }
                    // 私有key可写
                    if (certWriteMap.get("isPrivateKeyWrite") && !line.startsWith(ShellConstans.addSsl.START_PRIVKEY)) {
                        privekeySb.append(line);
                        privekeySb.append('\n');
                    }
                    //chain
                    if (line.startsWith(ShellConstans.addSsl.START_CHAIN)) {
                        certWriteMap.put("isChainWrite", true);
                    } else if (line.startsWith(ShellConstans.addSsl.END_CHAIN)) {
                        certWriteMap.put("isChainWrite", false);
                    }
                    // 私有key可写
                    if (certWriteMap.get("isChainWrite") && !line.startsWith(ShellConstans.addSsl.START_CHAIN)) {
                        chain.append(line);
                        chain.append('\n');
                    }
                }

                @Override
                public void stderr(String line) {
                    log.info("错误：" + line);
                }
            });
            adwebSite.setSiteCert(cert.toString());
            adwebSite.setSiteChain(chain.toString());
            adwebSite.setSitePrivkey(privekeySb.toString());
        }
        return adwebSite;
    }

    /**
     * @param adwebSite
     * @return
     */
    public Result<?> autoAddSslV2(AdwebSite adwebSite) {
        log.info("===== autoAddSslV2 ==> 开始生成SSL证书 domain:{},code:{},siteId:{} =====", adwebSite.getDomain(), adwebSite.getCode(), adwebSite.getId());
        String domainNew = adwebSite.getDomain().replace("http://", "").replace("https://", "").replace("www.", "");
        log.info("===== autoAddSslV2 ==> 开始生成SSL证书 domain:{},code:{},siteId:{},domainNew:{} =====", adwebSite.getDomain(), adwebSite.getCode(), adwebSite.getId(), domainNew);
//        domainNew = "xyexcavator.com";
//        String cmd = "sudo sh " + usWest118ServerShellPath + "/test_check_site_ssl_exist.sh " + adwebSite.getCode() + " " + domainNew;
//        String cmd = "sudo sh " + usWest118ServerShellPath + "/generate_site_ssl.sh " + adwebSite.getCode() + " " + domainNew;
        String cmd = "sudo sh " + usWest118ServerShellPath + "/switch_root_user.sh " + adwebSite.getCode() + " " + domainNew;
        log.info("===== autoAddSslV2 ==> 开始生成SSL证书 domain:{},code:{},siteId:{},domainNew:{},cmd:{} =====", adwebSite.getDomain(), adwebSite.getCode(), adwebSite.getId(), domainNew, cmd);
        try {
            String finalDomainNew = domainNew;
            final Map<String, Boolean> certWriteMap = new HashMap<>();
            certWriteMap.put("isCertWrite", false);
            certWriteMap.put("isPrivateKeyWrite", false);
            certWriteMap.put("isChainWrite", false);
            StringBuilder privateKey = new StringBuilder();
            StringBuilder cert = new StringBuilder();
            StringBuilder chain = new StringBuilder();
            shellService.exceShellByUsWest118(cmd, new ShellSSH2Util.StdoutListener() {
                @Override
                public void stdout(String line) {
                    log.info("标准 ：" + line);
                    //cert
                    if (line.startsWith(ShellConstans.addSsl.START_CERT)) {
                        certWriteMap.put("isCertWrite", true);
                    } else if (line.startsWith(ShellConstans.addSsl.END_CERT)) {
                        certWriteMap.put("isCertWrite", false);
                    }
                    if (certWriteMap.get("isCertWrite") && !line.startsWith(ShellConstans.addSsl.START_CERT)) {
                        cert.append(line);
                        cert.append('\n');
                    }

                    //privkey
                    if (line.startsWith(ShellConstans.addSsl.START_PRIVKEY)) {
                        certWriteMap.put("isPrivateKeyWrite", true);
                    } else if (line.startsWith(ShellConstans.addSsl.END_PRIVKEY)) {
                        certWriteMap.put("isPrivateKeyWrite", false);
                    }
                    if (certWriteMap.get("isPrivateKeyWrite") && !line.startsWith(ShellConstans.addSsl.START_PRIVKEY)) {
                        privateKey.append(line);
                        privateKey.append('\n');
                    }

                    //chain
                    if (line.startsWith(ShellConstans.addSsl.START_CHAIN)) {
                        certWriteMap.put("isChainWrite", true);
                    } else if (line.startsWith(ShellConstans.addSsl.END_CHAIN)) {
                        certWriteMap.put("isChainWrite", false);
                    }
                    if (certWriteMap.get("isChainWrite") && !line.startsWith(ShellConstans.addSsl.START_CHAIN)) {
                        chain.append(line);
                        chain.append('\n');
                    }

                    if ("SSL Certificate generation failed".equals(line)) {
                        log.info("======网站SSL证书生成失败======");
                        String title = "网站域名：" + finalDomainNew + " 站点SSL证书创建失败";
                        String message = "**站点ID:** " + adwebSite.getId() + "\n";
                        message += "**站点Code:** " + adwebSite.getCode() + "\n";
//                        message += "**服务器IP:** " + adwebSite.getProdServerIp() + "\n";
                        message += "**错误信息:** " + line + "\n";
                        sendAdWebV2FeiShuMsg(title, message);
                    }
                }

                @Override
                public void stderr(String line) {
                    log.info("错误 ：" + line);
                    String title = "网站域名：" + finalDomainNew + " 站点SSL证书创建失败";
                    String message = "**站点ID:** " + adwebSite.getId() + "\n";
                    message += "**站点Code:** " + adwebSite.getCode() + "\n";
//                    message += "**服务器IP:** " + adwebSite.getProdServerIp() + "\n";
                    message += "**错误信息:** " + line + "\n";
                    sendAdWebV2FeiShuMsg(title, message);
                }
            });

            if (StringUtils.isNotBlank(privateKey.toString()) && StringUtils.isNotBlank(cert.toString()) && StringUtils.isNotBlank(chain.toString())) {
                log.info("======= SSL证书获取成功 =======");
                log.info("privateKey:{}", privateKey);
                log.info("cert:{}", cert);
                log.info("chain:{}", chain);

                String certStr = cert.toString();
                boolean certStatus = certStr.contains("-----END CERTIFICATE-----");
                if (certStatus) {
                    int index = certStr.lastIndexOf("-----END CERTIFICATE-----");
                    certStr = certStr.substring(0, index + 25);
                }
                log.info("certStr:{}", certStr);

                // 站点SSL证书创建成功-操作
                log.info("======= 将证书信息保存至站点 =======");
                AdwebSite adwebSiteSSL = new AdwebSite();
                adwebSiteSSL.setId(adwebSite.getId());
                adwebSiteSSL.setSslOrigin(1);
                adwebSiteSSL.setSitePrivkey(privateKey.toString());
                adwebSiteSSL.setSiteCert(certStr);
                adwebSiteSSL.setSiteChain(chain.toString());
                adwebSiteSSL.setCretModifyTime(new Date());
                adwebSiteSSL.setUtime(new Date());
                siteService.updateById(adwebSiteSSL);

                //发送飞书消息
                String title = "网站域名：" + finalDomainNew + " 站点SSL证书创建成功";
                String message = "**站点ID:** " + adwebSite.getId() + "\n";
                message += "**站点Code:** " + adwebSite.getCode() + "\n";
//                message += "**服务器IP:** " + adwebSite.getProdServerIp() + "\n";
                sendAdWebV2FeiShuMsg(title, message);
//                return Result.OK("该站点SSL证书创建成功！");
                return domainHttpToHttps(adwebSite);
            } else {
                //发送飞书消息
                String title = "网站域名：" + finalDomainNew + " 站点SSL证书获取失败";
                String message = "**站点ID:** " + adwebSite.getId() + "\n";
                message += "**站点Code:** " + adwebSite.getCode() + "\n";
//                message += "**服务器IP:** " + adwebSite.getProdServerIp() + "\n";
                sendAdWebV2FeiShuMsg(title, message);
                return Result.error("该站点SSL证书获取失败！");
            }
        } catch (Exception e) {
            log.error("网站SSL证书创建失败退出执行；" + e.getMessage(), e);
            return Result.error("该站点SSL证书创建失败，请重试！");
        }
    }

    /**
     * 网站 http升级为https
     *
     * @param adwebSite
     * @return
     */
    public Result<?> domainHttpToHttps(AdwebSite adwebSite) {
        log.info("===== domainHttpToHttps ==> 开始执行将站点由http升级为https操作 domain:{},code:{},siteId:{} =====", adwebSite.getDomain(), adwebSite.getCode(), adwebSite.getId());
        String domainNew = adwebSite.getDomain().replace("http://", "").replace("https://", "").replace("www.", "");
        log.info("===== domainHttpToHttps ==> 开始执行将站点由http升级为https操作 domain:{},code:{},siteId:{},domainNew:{} =====", adwebSite.getDomain(), adwebSite.getCode(), adwebSite.getId(), domainNew);
        String cmd = "sudo sh " + usWest118ServerShellPath + "/adweb-publish_https.sh " + adwebSite.getCode() + " " + domainNew;
        log.info("===== domainHttpToHttps ==> 开始执行将站点由http升级为https操作 domain:{},code:{},siteId:{},domainNew:{},cmd:{} =====", adwebSite.getDomain(), adwebSite.getCode(), adwebSite.getId(), domainNew, cmd);
        try {
            shellService.exceShellByUsWest118(cmd, new ShellSSH2Util.StdoutListener() {
                @Override
                public void stdout(String line) {
                    log.info("标准 ：" + line);
                    if ("Site Https Created successfully".equals(line)) {
                        log.info("======网站http升级为https成功======");
                        String title = "网站域名：" + domainNew + " 站点http升级为https成功";
                        String message = "**站点ID:** " + adwebSite.getId() + "\n";
                        message += "**站点Code:** " + adwebSite.getCode() + "\n";
//                        message += "**服务器IP:** " + adwebSite.getProdServerIp() + "\n";
                        message += "**成功信息:** " + line + "\n";
                        sendAdWebV2FeiShuMsg(title, message);

                        log.info("======网站http升级为https成功，开始更新站点信息======");
                        adwebSite.setDomain("https://" + domainNew);
                        siteService.updateById(adwebSite);
                    }

                    if ("test nginx failed".equals(line) || "SSL Certificate not found".equals(line)) {
                        log.info("======网站http升级为https失败======");
                        String title = "网站域名：" + domainNew + " 站点http升级为https失败";
                        String message = "**站点ID:** " + adwebSite.getId() + "\n";
                        message += "**站点Code:** " + adwebSite.getCode() + "\n";
//                        message += "**服务器IP:** " + adwebSite.getProdServerIp() + "\n";
                        message += "**错误信息:** " + line + "\n";
                        sendAdWebV2FeiShuMsg(title, message);
                    }
                }

                @Override
                public void stderr(String line) {
                    log.info("错误 ：" + line);
                    String title = "网站域名：" + domainNew + " 站点http升级为https失败";
                    String message = "**站点ID:** " + adwebSite.getId() + "\n";
                    message += "**站点Code:** " + adwebSite.getCode() + "\n";
//                    message += "**服务器IP:** " + adwebSite.getProdServerIp() + "\n";
                    message += "**错误信息:** " + line + "\n";
                    sendAdWebV2FeiShuMsg(title, message);
                }
            });
            return Result.OK();
        } catch (Exception e) {
            log.error("网站http升级为https失败退出执行；" + e.getMessage(), e);
            return Result.error("该站点http升级为https失败，请重试！");
        }
    }


    /**
     * 手动添加SSL
     *
     * @param adwebSite
     * @return
     */
    public void munualAddSSL(AdwebSite adwebSite, String fullchainUrl, String privkeyUrl) {
        String cmd = "./shell/add_ssl " + wpSiteReleasePrivateIp + " " + adwebSite.getCode() + " " + adwebSite.getInCode() + " " + adwebSite.getDomain() + " " + fullchainUrl + " " + privkeyUrl;
        shellService.exceShell(cmd, new ShellSSH2Util.StdoutListener() {
            @Override
            public void stdout(String line) {
                log.info("控制台：" + line);
                if (line.contains("EXIST!")) {
                    log.info("更新！");
                }
            }

            @Override
            public void stderr(String line) {
                log.info("错误 ：" + line);
            }
            //TODO 脚本异常处理
        });
    }


    /**
     * @param msgTitle
     * @param message
     */
    public void sendAdWebV2FeiShuMsg(String msgTitle, String message) {
        try {
            openFeishuMsgService.sendAdWebV2FeiShuMsg(msgTitle, message);
        } catch (NoSuchAlgorithmException | InvalidKeyException e) {
            throw new RuntimeException(e);
        }
    }
}
