package com.tongran.mtragent.service.impl;

import com.tongran.common.core.constant.SecurityConstants;
import com.tongran.common.core.domain.R;
import com.tongran.common.core.utils.DateUtils;
import com.tongran.common.core.utils.StringUtils;
import com.tongran.common.security.utils.SecurityUtils;
import com.tongran.mtragent.domain.RmMtrClientRegistration;
import com.tongran.mtragent.domain.RmMtrPolicyConfig;
import com.tongran.mtragent.mapper.RmMtrClientRegistrationMapper;
import com.tongran.mtragent.mapper.RmMtrPolicyConfigMapper;
import com.tongran.mtragent.service.IRmMtrPolicyConfigService;
import com.tongran.system.api.RemoteRocketMqService;
import com.tongran.system.api.domain.RmNetworkInterfaceRemote;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * mtr探测策略配置Service业务层处理
 * 
 * @author tongran
 * @date 2025-11-18
 */
@Service
public class RmMtrPolicyConfigServiceImpl implements IRmMtrPolicyConfigService 
{
    @Autowired
    private RmMtrPolicyConfigMapper rmMtrPolicyConfigMapper;
    @Autowired
    private RmMtrClientRegistrationMapper rmMtrClientRegistrationMapper;
    @Autowired
    private RemoteRocketMqService remoteRocketMqService;

    /**
     * 查询mtr探测策略配置
     * 
     * @param id mtr探测策略配置主键
     * @return mtr探测策略配置
     */
    @Override
    public RmMtrPolicyConfig selectRmMtrPolicyConfigById(Long id)
    {
        RmMtrPolicyConfig mtrPolicyConfig = rmMtrPolicyConfigMapper.selectRmMtrPolicyConfigById(id);
        mtrPolicyConfig.setServerGroup(mtrPolicyConfig.getServerGroup().replace("\n", ";"));
        return mtrPolicyConfig;
    }

    /**
     * 查询mtr探测策略配置列表
     * 
     * @param rmMtrPolicyConfig mtr探测策略配置
     * @return mtr探测策略配置
     */
    @Override
    public List<RmMtrPolicyConfig> selectRmMtrPolicyConfigList(RmMtrPolicyConfig rmMtrPolicyConfig)
    {
        List<RmMtrPolicyConfig> list = rmMtrPolicyConfigMapper.selectRmMtrPolicyConfigList(rmMtrPolicyConfig);
        for (RmMtrPolicyConfig mtrPolicyConfig : list) {
            mtrPolicyConfig.setServerGroup(mtrPolicyConfig.getServerGroup().replace("\n", ";"));
        }
        return list;
    }

    /**
     * 辅助方法，给ip集合赋值
     * @param mtrPolicyConfig
     */
    public void setServerip(RmMtrPolicyConfig mtrPolicyConfig) {
        StringJoiner resultJoiner = new StringJoiner(";");
        String serverGroupStr = mtrPolicyConfig.getServerGroup().replace("\n", ",");
        String[] serverIds = serverGroupStr.split(",");

        // 分批次处理，每批200个
        int batchSize = 200;
        for (int i = 0; i < serverIds.length; i += batchSize) {
            int end = Math.min(i + batchSize, serverIds.length);

            // 构建当前批次的id字符串
            StringBuilder batchIds = new StringBuilder();
            for (int j = i; j < end; j++) {
                if (batchIds.length() > 0) {
                    batchIds.append(",");
                }
                batchIds.append(serverIds[j].trim());
            }

            // 查询当前批次
            RmNetworkInterfaceRemote query = new RmNetworkInterfaceRemote();
            query.setClientIds(batchIds.toString());
            R<List<RmNetworkInterfaceRemote>> networkList = remoteRocketMqService.getNetworkInterfaceList(query, SecurityConstants.INNER);

            // 处理结果
            if (networkList != null && networkList.getData() != null) {
                for (RmNetworkInterfaceRemote rmNetworkInterfaceRemote : networkList.getData()) {
                    String publicIp = rmNetworkInterfaceRemote.getPublicIp();
                    if (publicIp != null && !publicIp.trim().isEmpty()) {
                        resultJoiner.add(publicIp);
                    }
                }
            }
        }

        // 设置最终结果
        String result = resultJoiner.toString();
        if (!result.isEmpty()) {
            mtrPolicyConfig.setServeripGroup(result);
        }
    }
    /**
     * 辅助方法，给ip集合一一对应赋值
     * @param mtrPolicyConfig
     */
    public void setServeripToClientId(RmMtrPolicyConfig mtrPolicyConfig){
        String serverGroupStr = mtrPolicyConfig.getServerGroup();
        if(serverGroupStr == null){
            return;
        }
        // 使用Set自动去重
        Set<String> allIpsSet = new HashSet<>();
        String[] clientIds = serverGroupStr.split("\n");
        Map<String, List<String>> clientIdToIpsMap = new HashMap<>();
        for (String clientId : clientIds) {
            RmNetworkInterfaceRemote query = new RmNetworkInterfaceRemote();
            query.setClientIds(clientId);
            R<List<RmNetworkInterfaceRemote>> networkList = remoteRocketMqService.getNetworkInterfaceList(query, SecurityConstants.INNER);
            if(networkList != null && networkList.getData() != null){
                List<RmNetworkInterfaceRemote> rmNetworkInterfaceRemoteList = networkList.getData();
                if(!rmNetworkInterfaceRemoteList.isEmpty()){
                    for (RmNetworkInterfaceRemote rmNetworkInterfaceRemote : rmNetworkInterfaceRemoteList) {
                        List<String> ips = networkList.getData().stream()
                                .map(RmNetworkInterfaceRemote::getPublicIp)
                                .filter(StringUtils::isNotBlank)
                                .collect(Collectors.toList());
                        if (!ips.isEmpty()) {
                            clientIdToIpsMap.put(clientId, ips);
                            allIpsSet.addAll(ips); // 自动去重
                        }
                        clientIdToIpsMap.put(clientId, ips);
                    }
                    // 将Set转换为分号分隔的字符串
                    String allIps = String.join(";", allIpsSet);
                    mtrPolicyConfig.setServeripGroup(allIps);
                    mtrPolicyConfig.setClientIdToIpsMap(clientIdToIpsMap);
                }
            }
        }
    }
    /**
     * 新增mtr探测策略配置
     *
     * @param rmMtrPolicyConfig mtr探测策略配置
     * @return 结果
     */
    @Override
    public int insertRmMtrPolicyConfig(RmMtrPolicyConfig rmMtrPolicyConfig)
    {
        // 检查是否超出限制
        checkServerNum(rmMtrPolicyConfig);
        rmMtrPolicyConfig.setCreateTime(DateUtils.getNowDate());
        rmMtrPolicyConfig.setUpdateTime(DateUtils.getNowDate());
        rmMtrPolicyConfig.setCreateBy(SecurityUtils.getUsername());
        // 数据表触发器，优先级自增
        rmMtrPolicyConfig.setPriority(null);
        // 给ip赋值
        setServerip(rmMtrPolicyConfig);
        int rows = rmMtrPolicyConfigMapper.insertRmMtrPolicyConfig(rmMtrPolicyConfig);
        return rows;
    }

    /**
     * 修改mtr探测策略配置
     *
     * @param rmMtrPolicyConfig mtr探测策略配置
     * @return 结果
     */
    @Override
    public int updateRmMtrPolicyConfig(RmMtrPolicyConfig rmMtrPolicyConfig)
    {
        // 检查是否超出限制
        checkServerNum(rmMtrPolicyConfig);
        rmMtrPolicyConfig.setUpdateTime(DateUtils.getNowDate());
        // 给ip赋值
        setServerip(rmMtrPolicyConfig);
        return rmMtrPolicyConfigMapper.updateRmMtrPolicyConfig(rmMtrPolicyConfig);
    }

    public void checkServerNum(RmMtrPolicyConfig rmMtrPolicyConfig){
        if (rmMtrPolicyConfig.getMtrClientId() == null) {
            throw new RuntimeException("MTR客户端ID不能为空");
        }
        // 获取CPU核心数
        int cpuCores = getCpuCores(rmMtrPolicyConfig.getMtrClientId());
        if(cpuCores == 0){
            // cpu核数未采集
            throw new RuntimeException("该MTRAgent的cpu核数未上报，请检查详情，待cpu核数上报后重试");
        }
        Set<String> serverSet = isPolicyCountExceeded(rmMtrPolicyConfig);
        if(serverSet == null) {
            return; // 没有服务器或客户端ID为空，直接返回
        }
        if(serverSet.size() > cpuCores){
            // 设置错误信息，包含已下发的服务器列表
            String errorMessage = String.format("探测服务器数量超过节点并发数量限制(%d)，已开启探测的服务器clientId为: %s",
                    cpuCores, String.join(", ", serverSet));
            throw new RuntimeException(errorMessage);
        }
    }
    /**
     * 检查策略数量是否超过CPU核心数限制
     *
     * @param newPolicy 新增或修改的策略
     * @return true-超过限制，false-未超过限制
     */
    private Set<String> isPolicyCountExceeded(RmMtrPolicyConfig newPolicy) {

        // 获取当前客户端应该执行的策略列表
        List<RmMtrPolicyConfig> currentPolicies = getPoliciesForMtrClient(newPolicy.getMtrClientId());

        // 获取新策略中的服务器ID列表（去重）
        List<String> newServerIds = getServerIdsFromPolicy(newPolicy);
        if (newServerIds.isEmpty()) {
            return null;
        }

        // 获取当前已分配的服务器ID列表（去重）
        Set<String> currentServerIds = new HashSet<>();
        for (RmMtrPolicyConfig policy : currentPolicies) {
            // 如果是修改操作，需要排除当前策略本身
            if (newPolicy.getId() != null &&
                    newPolicy.getId().equals(policy.getId())) {
                continue; // 跳过当前正在修改的策略
            }
            List<String> serverIds = getServerIdsFromPolicy(policy);
            currentServerIds.addAll(serverIds);
        }

        // 计算新增的不重复服务器数量
        Set<String> allServerIds = new HashSet<>(currentServerIds);
        allServerIds.addAll(newServerIds);
        return allServerIds;
    }
    /**
     * 获取CPU核心数
     */
    private int getCpuCores(String mtrClientId) {
        RmMtrClientRegistration query = new RmMtrClientRegistration();
        query.setMtrClientId(mtrClientId);
        RmMtrClientRegistration rmMtrRegistMsg = rmMtrClientRegistrationMapper.getMsgByMtrClientId(query);
        if(rmMtrRegistMsg != null && rmMtrRegistMsg.getCpucores() != null){
            return rmMtrRegistMsg.getCpucores() * 2;
        }
        return 0;
    }

    /**
     * 批量删除mtr探测策略配置
     * 
     * @param ids 需要删除的mtr探测策略配置主键
     * @return 结果
     */
    @Override
    public int deleteRmMtrPolicyConfigByIds(Long[] ids)
    {
        return rmMtrPolicyConfigMapper.deleteRmMtrPolicyConfigByIds(ids);
    }

    /**
     * 删除mtr探测策略配置信息
     * 
     * @param id mtr探测策略配置主键
     * @return 结果
     */
    @Override
    public int deleteRmMtrPolicyConfigById(Long id)
    {
        return rmMtrPolicyConfigMapper.deleteRmMtrPolicyConfigById(id);
    }
    /**
     * 根据MTR客户端ID获取应该下发的策略列表
     *
     * @param mtrClientId MTR客户端ID
     * @return 策略列表
     */
    @Override
    public List<RmMtrPolicyConfig> getPoliciesForMtrClient(String mtrClientId) {
        List<RmMtrPolicyConfig> result = new ArrayList<>();
        if (mtrClientId == null || mtrClientId.trim().isEmpty()) {
            return result;
        }

        // 查询所有策略
        RmMtrPolicyConfig query = new RmMtrPolicyConfig();
        List<RmMtrPolicyConfig> allPolicies = rmMtrPolicyConfigMapper.selectRmMtrPolicyConfigList(query);

        if (allPolicies == null || allPolicies.isEmpty()) {
            return result;
        }

        // 按优先级降序排序（优先级高的在前面）
        List<RmMtrPolicyConfig> sortedPolicies = allPolicies.stream()
                .filter(p -> p.getPriority() != null && p.getProbeFlag() != null)
                .sorted((p1, p2) -> Long.compare(p2.getPriority(), p1.getPriority()))
                .collect(Collectors.toList());

        // 构建最终的服务器分配映射
        Map<String, String> serverAssignment = new HashMap<>();

        // 从高优先级到低优先级处理策略
        for (RmMtrPolicyConfig policy : sortedPolicies) {
            List<String> serverIds = getServerIdsFromPolicy(policy);
            if (serverIds.isEmpty()) {
                continue;
            }

            // 处理每个服务器：只有这个服务器还没有被处理过时，才处理当前策略
            for (String serverId : serverIds) {
                if (!serverAssignment.containsKey(serverId)) {
                    if (policy.getProbeFlag() == 1) {
                        // 探测：记录分配给哪个MTR客户端
                        serverAssignment.put(serverId, policy.getMtrClientId());
                    } else {
                        // 不探测：记录为null
                        serverAssignment.put(serverId, null);
                    }
                }
            }
        }

        // 找出应该由当前请求客户端执行的服务器
        List<String> assignedServers = new ArrayList<>();
        for (Map.Entry<String, String> entry : serverAssignment.entrySet()) {
            String serverId = entry.getKey();
            String assignedClientId = entry.getValue();

            // 只有当分配给的客户端是当前请求客户端，且不是null（即需要探测）时
            if (mtrClientId.equals(assignedClientId)) {
                assignedServers.add(serverId);
            }
        }

        // 如果没有服务器分配给当前客户端，返回空列表
        if (assignedServers.isEmpty()) {
            return result;
        }

        // 找出每个服务器最终生效的策略（最高优先级的那个）
        Map<RmMtrPolicyConfig, List<String>> policyServersMap = new HashMap<>();
        for (String serverId : assignedServers) {
            RmMtrPolicyConfig finalPolicy = findFinalPolicyForServer(serverId, sortedPolicies);
            if (finalPolicy != null) {
                policyServersMap.computeIfAbsent(finalPolicy, k -> new ArrayList<>()).add(serverId);
            }
        }

        // 创建策略副本返回
        for (Map.Entry<RmMtrPolicyConfig, List<String>> entry : policyServersMap.entrySet()) {
            RmMtrPolicyConfig newPolicy = createPolicyCopy(entry.getKey(), entry.getValue());
            setServeripToClientId(newPolicy);
            result.add(newPolicy);
        }

        return result;
    }

    /**
     * 找出服务器最终生效的策略（最高优先级的那个）
     */
    private RmMtrPolicyConfig findFinalPolicyForServer(String serverId, List<RmMtrPolicyConfig> sortedPolicies) {
        for (RmMtrPolicyConfig policy : sortedPolicies) {
            if (containsServer(policy, serverId)) {
                return policy;
            }
        }
        return null;
    }

    /**
     * 从策略中提取服务器ID列表
     */
    private List<String> getServerIdsFromPolicy(RmMtrPolicyConfig policy) {
        List<String> serverIds = new ArrayList<>();
        if (policy.getServerGroup() != null) {
            String serverGroup = policy.getServerGroup();
            String[] ids = serverGroup.split("\n");
            for (String id : ids) {
                if (id != null && !id.trim().isEmpty()) {
                    serverIds.add(id.trim());
                }
            }
            // 如果列表为空，直接返回空列表，避免不必要的数据库查询
            if (serverIds.isEmpty()) {
                return serverIds;
            }
            // 过滤离线的服务器
            serverIds = rmMtrPolicyConfigMapper.getOnlineServerId(serverIds);
        }
        return serverIds;
    }

    /**
     * 检查策略是否包含指定服务器
     */
    private boolean containsServer(RmMtrPolicyConfig policy, String serverId) {
        List<String> serverIds = getServerIdsFromPolicy(policy);
        return serverIds.contains(serverId);
    }

    /**
     * 创建策略副本
     */
    private RmMtrPolicyConfig createPolicyCopy(RmMtrPolicyConfig original, List<String> serverIds) {
        RmMtrPolicyConfig copy = new RmMtrPolicyConfig();
        copy.setId(original.getId());
        copy.setPolicyName(original.getPolicyName());
        copy.setPriority(original.getPriority());
        copy.setMtrClientId(original.getMtrClientId());
        copy.setProbeFlag(original.getProbeFlag());
        copy.setStartTime(original.getStartTime());
        copy.setEndTime(original.getEndTime());
        copy.setProbeFrequency(original.getProbeFrequency());

        // 服务器组用换行符连接
        copy.setServerGroup(String.join("\n", serverIds));
        copy.setServeripGroup(original.getServeripGroup());

        copy.setCreateTime(original.getCreateTime());
        copy.setUpdateTime(original.getUpdateTime());
        copy.setCreateBy(original.getCreateBy());
        copy.setUpdateBy(original.getUpdateBy());

        return copy;
    }
}
