package com.ruoyi.rocketmq.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.rocketmq.domain.DeviceMessage;
import com.ruoyi.rocketmq.domain.RmAlarmPolicy;
import com.ruoyi.rocketmq.domain.RmAlarmRule;
import com.ruoyi.rocketmq.domain.vo.AlarmVo;
import com.ruoyi.rocketmq.mapper.RmAlarmPolicyMapper;
import com.ruoyi.rocketmq.mapper.RmAlarmRuleMapper;
import com.ruoyi.rocketmq.model.ProducerMode;
import com.ruoyi.rocketmq.producer.MessageProducer;
import com.ruoyi.rocketmq.service.IRmAlarmPolicyService;
import com.ruoyi.rocketmq.utils.DataProcessUtil;
import com.ruoyi.system.api.domain.RmResourceRegistrationRemote;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 告警策略Service业务层处理
 * 
 * @author gyt
 * @date 2025-09-12
 */
@Service
@Slf4j
public class RmAlarmPolicyServiceImpl implements IRmAlarmPolicyService 
{
    @Autowired
    private ProducerMode producerMode;
    @Autowired
    private RmAlarmPolicyMapper rmAlarmPolicyMapper;
    @Autowired
    private RmAlarmRuleMapper rmAlarmRuleMapper;
    @Autowired
    private DataProcessUtil dataProcessUtil;

    /**
     * 查询告警策略
     * 
     * @param id 告警策略主键
     * @return 告警策略
     */
    @Override
    public RmAlarmPolicy selectRmAlarmPolicyById(Long id)
    {
        return rmAlarmPolicyMapper.selectRmAlarmPolicyById(id);
    }

    /**
     * 查询告警策略列表
     * 
     * @param rmAlarmPolicy 告警策略
     * @return 告警策略
     */
    @Override
    public List<RmAlarmPolicy> selectRmAlarmPolicyList(RmAlarmPolicy rmAlarmPolicy)
    {
        List<RmAlarmPolicy> list = rmAlarmPolicyMapper.selectRmAlarmPolicyList(rmAlarmPolicy);
        for (RmAlarmPolicy alarmPolicy : list) {
            // 资源组名称
            alarmPolicy.setResourceGroupName(dataProcessUtil.getResourceGroupNameById(alarmPolicy.getResourceGroupId()));
            // 包含设备
            alarmPolicy.setResourceName(dataProcessUtil.getResourceMsgById(alarmPolicy.getResourceGroupId()).getIncludedDevicesName());
        }
        return list;
    }

    /**
     * 新增告警策略
     * 
     * @param rmAlarmPolicy 告警策略
     * @return 结果
     */
    @Override
    public int insertRmAlarmPolicy(RmAlarmPolicy rmAlarmPolicy)
    {
        rmAlarmPolicy.setCreateTime(DateUtils.getNowDate());
        return rmAlarmPolicyMapper.insertRmAlarmPolicy(rmAlarmPolicy);
    }

    /**
     * 修改告警策略
     * 
     * @param rmAlarmPolicy 告警策略
     * @return 结果
     */
    @Override
    public int updateRmAlarmPolicy(RmAlarmPolicy rmAlarmPolicy)
    {
        rmAlarmPolicy.setUpdateTime(DateUtils.getNowDate());
        rmAlarmPolicy.setStatus("0");
        rmAlarmPolicyMapper.updateRmAlarmPolicy(rmAlarmPolicy);
        // 删除已有信息
        rmAlarmRuleMapper.deleteRmAlarmRuleByPolicyId(rmAlarmPolicy.getId());
        // 新增告警规则信息
        for (RmAlarmRule alarmRule : rmAlarmPolicy.getAlarmRuleList()) {
            alarmRule.setAlarmPolicyId(rmAlarmPolicy.getId());
        }
        rmAlarmRuleMapper.batchInsertRmAlarmRule(rmAlarmPolicy.getAlarmRuleList());
        return 1;
    }

    /**
     * 批量删除告警策略
     * 
     * @param ids 需要删除的告警策略主键
     * @return 结果
     */
    @Override
    public int deleteRmAlarmPolicyByIds(Long[] ids)
    {
        return rmAlarmPolicyMapper.deleteRmAlarmPolicyByIds(ids);
    }

    /**
     * 删除告警策略信息
     * 
     * @param id 告警策略主键
     * @return 结果
     */
    @Override
    public int deleteRmAlarmPolicyById(Long id)
    {
        return rmAlarmPolicyMapper.deleteRmAlarmPolicyById(id);
    }

    /**
     * 告警管理详情
     * @param id
     * @return
     */
    @Override
    public Map getRmAlarmPolicyMsgById(Long id) {
        Map map = new HashMap();
        // 告警策略基础信息
        RmAlarmPolicy alarmPolicy = rmAlarmPolicyMapper.selectRmAlarmPolicyById(id);
        alarmPolicy.setResourceGroupName(dataProcessUtil.getResourceGroupNameById(alarmPolicy.getResourceGroupId()));
        map.put("alarmPolicy", alarmPolicy);
        // 策略内容
        RmAlarmRule alarmRule = new RmAlarmRule();
        alarmRule.setAlarmPolicyId(id);
        List<RmAlarmRule> ruleList = rmAlarmRuleMapper.selectRmAlarmRuleList(alarmRule);
        List<RmAlarmRule> linuxRuleList = ruleList.stream().filter(
                rule -> "linux".equals(rule.getResourceType())
        ).collect(Collectors.toList());
        List<RmAlarmRule> switchRuleList = ruleList.stream().filter(
                rule -> "switch".equals(rule.getResourceType())
        ).collect(Collectors.toList());
        map.put("linuxRule", linuxRuleList);
        map.put("switchRule", switchRuleList);
        return map;
    }

    /**
     * 新增告警策略
     * @param rmAlarmPolicy
     * @return
     */
    @Override
    public int addRmAlarmPolicy(RmAlarmPolicy rmAlarmPolicy) {
        // 基础信息
        rmAlarmPolicyMapper.insertRmAlarmPolicy(rmAlarmPolicy);
        // linux/switch信息
        rmAlarmRuleMapper.batchInsertRmAlarmRule(rmAlarmPolicy.getAlarmRuleList());
        return 1;
    }

    /**
     * 下发告警策略
     * @param id
     * @return
     */
    @Override
    public int issueAlarmPolicy(Long id) {
        RmAlarmPolicy rmAlarmPolicy = rmAlarmPolicyMapper.selectRmAlarmPolicyById(id);
        if (rmAlarmPolicy == null) {
            log.error("策略不存在，id: {}", id);
            return 0;
        }
        // 资源信息
        List<RmResourceRegistrationRemote> devices = dataProcessUtil.getResourceDevices(rmAlarmPolicy.getResourceGroupId());
        // 告警规则信息
        Map<String,Object> alarmPolicyMsg = getRmAlarmPolicyMsgById(id);
        // 构建消息内容
        List<AlarmVo> alarmVos = buildAlarmConfigurations(alarmPolicyMsg);
        // 发送消息
        sendConfigurationsToDevices(devices, alarmVos);
        // 更新告警策略状态为已下发
        RmAlarmPolicy alarmPolicy = new RmAlarmPolicy();
        alarmPolicy.setId(id);
        alarmPolicy.setStatus("1");
        rmAlarmPolicyMapper.updateRmAlarmPolicy(alarmPolicy);
        return 1;
    }
    /**
     * 构建采集配置
     */
    private List<AlarmVo> buildAlarmConfigurations(Map<String, Object> alarmPolicyDetails) {
        List<AlarmVo> alarmVos = new ArrayList<>();
        // 拿到告警规则信息
        List<RmAlarmRule> linuxRule = (List<RmAlarmRule>) alarmPolicyDetails.get("linuxRule");
        for (RmAlarmRule alarmRule : linuxRule) {
            AlarmVo alarmVo = new AlarmVo();
            alarmVo.setType(alarmRule.getMetricKey());
            alarmVo.setCollect(true);
            alarmVo.setOperator(alarmRule.getOperator());
            alarmVo.setThreshold(alarmRule.getThreshold());
            alarmVo.setStatus(alarmRule.getStatus());
            alarmVo.setPortWhitelist(alarmRule.getPortWhitelist());
        }
        return alarmVos;
    }
    /**
     * 发送配置到设备
     */
    private void sendConfigurationsToDevices(List<RmResourceRegistrationRemote> devices, List<AlarmVo> alarmVos) {
        MessageProducer messageProducer = new MessageProducer();
        Map map = new HashMap();
        map.put("alarmRules", alarmVos);
        String configJson = JSONObject.toJSONString(map);

        for (RmResourceRegistrationRemote device : devices) {
            try {
                DeviceMessage message = new DeviceMessage();
                message.setClientId(device.getHardwareSn());
                message.setData(configJson);
                message.setDataType("SYSTEM_COLLECT_START");

                messageProducer.sendAsyncProducerMessage(
                        producerMode.getAgentTopic(),
                        "",
                        "",
                        JSONObject.toJSONString(message)
                );
            } catch (Exception e) {
                log.error("发送设备配置失败，deviceId: {}", device.getHardwareSn(), e);
            }
        }
    }
}
