package io.wdd.func.xray.service;

import io.wdd.common.utils.TimeUtils;
import io.wdd.func.oss.config.OctopusObjectSummary;
import io.wdd.func.xray.beans.node.ProxyNode;
import io.wdd.rpc.execute.service.ExecutionService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 需要完成 Tmp目录中Xray文件的上传工作，上传至 OSS中
 * <p>
 * 生成操作命令
 * 调用rpc，执行命令下发操作，等待agent进行相关操作
 * <p>
 * 检查任务流程的结果，判断是否符合预期
 */
@Service
@Slf4j
public class XrayCallAgent {

    /**
     * 存储更新 Xray的命令行
     */
    private static final List<List<String>> updateXrayCommandList = new ArrayList<>();

    /**
     * 发送至agent的操作类型
     */
    private static final String updateCommandType = "OctopusXray";

    static {

        ArrayList<String> first = new ArrayList<>(
                List.of(
                        "mv",
                        "/usr/local/etc/xray/config.json",
                        "/usr/local/etc/xray/config-bak-TIME"
                )
        );

        ArrayList<String> second = new ArrayList<>(
                List.of(
                        "wget",
                        "AGENT_SPECIFIC_CONFIG_URL",
                        "-O",
                        "/usr/local/etc/xray/config.json"
                )
        );

        ArrayList<String> third = new ArrayList<>(
                List.of(
                        "systemctl",
                        "restart",
                        "xray"
                )
        );

        ArrayList<String> fourth = new ArrayList<>(
                List.of(
                        "systemctl",
                        "status",
                        "xray",
                        "|",
                        "grep",
                        "-c",
                        "active (running)"
                )
        );

        updateXrayCommandList.add(first);
        updateXrayCommandList.add(second);
        updateXrayCommandList.add(third);
        updateXrayCommandList.add(fourth);

    }

    @Resource
    ExecutionService executionService;

    /**
     * 为代理链的每一个节点 构建Xray配置更新命令，然后发送至对应的Agent中
     */
    public void buildXrayUpdateCommandAndCallAgent(Collection<ProxyNode> allProxyNodeList) {

        String formatTimeString = TimeUtils.currentFormatTimeString();

        List<String> resultKeyList = allProxyNodeList
                .stream()
                .map(
                        proxyNode -> {
                            OctopusObjectSummary.AccessDTO access = proxyNode
                                    .getXrayConfigInfo()
                                    .getObjectSummary()
                                    .getAccess();

                            String realUrl = String.valueOf(access
                                                                    .getOriginUrl());

                            if (StringUtils.isNotEmpty(access.getCloudflareUrl())) {
                                // 优先使用 被cloudflare包装过的的下载网址
                                realUrl = access.getCloudflareUrl();
                            }
                            // 修改命令中的时间
                            String s = updateXrayCommandList
                                    .get(0)
                                    .get(2);
                            updateXrayCommandList
                                    .get(0)
                                    .set(
                                            2,
                                            s.replace(
                                                    "TIME",
                                                    formatTimeString
                                            )
                                    );

                            // 修改命令中的下载url
                            updateXrayCommandList
                                    .get(1)
                                    .set(
                                            1,
                                            realUrl
                                    );

                            // 向Agent发送命令，执行更新操作！
                            executionService.SendCommandToAgent(
                                    proxyNode.getAgentTopicName(),
                                    updateCommandType,
                                    null,
                                    null,
                                    null,
                                    updateXrayCommandList,
                                    false,
                                    false
                            );

                            return "";
                        }
                )
                .collect(Collectors.toList());

        log.info(
                "为代理链的每一个节点 构建Xray配置更新命令，然后发送至对应的Agent中成功， 结果查看为 => {}",
                resultKeyList
        );

    }


}
