package com.common.service;



import com.common.entity.Alarm;
import com.common.entity.AlarmVisit;
import com.common.entity.GroupedSyslogData;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

@Slf4j
@Component
public class DataTransformer {

    /**
     * 转换分组数据为告警记录
     */
    public List<Alarm> transformGroupedData(List<GroupedSyslogData> groupedDataList) {
        List<Alarm> alarmList = new ArrayList<>(groupedDataList.size());

        for (GroupedSyslogData groupedData : groupedDataList) {
            Alarm alarm = transformSingleGroupedData(groupedData);
            if (alarm != null) {
                alarmList.add(alarm);
            }
        }

        return alarmList;
    }

    /**
     * 转换分组数据为告警记录
     */
    public List<AlarmVisit> transformGroupedDataVisit(List<GroupedSyslogData> groupedDataList) {
        List<AlarmVisit> alarmList = new ArrayList<>(groupedDataList.size());

        for (GroupedSyslogData groupedData : groupedDataList) {
            AlarmVisit alarm = transformSingleGroupedDataVisit(groupedData);
            if (alarm != null) {
                alarmList.add(alarm);
            }
        }

        return alarmList;
    }

    private Alarm transformSingleGroupedData(GroupedSyslogData groupedData) {
        try {
            return Alarm.builder()
                    .id(UUID.randomUUID().toString())
                    .createdAt(LocalDateTime.now())
                    .alarmName( groupedData.getOriginEventName())
                    .alarmLevel(convertAlarmLevel(groupedData.getMaxEventLevel()))
                    .alarmType(getAlarmType(groupedData.getFirstEventType(),groupedData.getMinEventType()))
                    .alarmMajorType(groupedData.getEventType())
                    .alarmMinorType(groupedData.getMinEventType())
                    .alarmAreaId(0)
                    .attackIp(groupedData.getAttackIps())
                    .victimIp(groupedData.getVictimIps())
                    .victimWebUrl(groupedData.getVictimWebUrls())
                    .attackChainPhase(new Integer[]{-1})
                    .deviceId(groupedData.getDeviceIds())
                    .tag(null)
                    .comment(buildComment(groupedData))
                    .originLogIds(groupedData.getOriginLogIds())
                    .queryId(null)
                    .judgedState(0)
                    .disposedState(0)
                    .dispositionAdvice("研判后处置")
                    .attackResult(determineAttackResult(groupedData))
                    .fall(0)
                    .payload(extractPayloadSample(groupedData.getPayloadSamples()))
                    .operateEvent(null)
                    .attackPort(groupedData.getAttackPorts())
                    .victimPort(groupedData.getVictimPorts())
                    .attackMethod(groupedData.getOriginEventName())
                    .businessExt(null)
                    .logStartAt(groupedData.getMinLogTime())
                    .logEndAt(groupedData.getMaxLogTime())
                    .httpStatus(convertHttpStatus(groupedData.getHttpStatusCodes()))
                    .dnsInfo(groupedData.getDnsInfo())
                    .accountInfo(null)
                    .attackerInfo(null)
                    .victimInfo(null)
                    .suspiciousAction(null)
                    .vulnInfo(null)
                    .weakPwd(null)
                    .complianceBaseline(null)
                    .fileInfo(null)
                    .fileTags(null)
                    .endpointInfo(null)
                    .endpointProtection(null)
                    .originInfo(null)
                    .protocolInfo(null)
                    .emailInfo(null)
                    .sensitiveData(null)
                    .hitIntelligence(0)
                    .windowTime(null)
                    .updatedAt(LocalDateTime.now())
                    .engineType(null)
                    .attackIpPic(null)
                    .victimIpPic(null)
                    .operationAt(null)
                    .attackDirection("other")
                    .etlTime(LocalDateTime.now())
                    .logCount(groupedData.getLogCount().intValue())
                    .isAssetHit(0)
                    .focused(false)
                    .baseFocused(false)
                    .isUpdated(false)
                    .httpReqHeader(groupedData.getHttpReqHeaders())
                    .httpReqBody(groupedData.getHttpReqBodys())
                    .httpRespHeader(groupedData.getHttpRespHeaders())
                    .httpRespBody(groupedData.getHttpRespBodys())
                    .build();

        } catch (Exception e) {
            log.error("转换分组数据失败: {}", groupedData, e);
            return null;
        }
    }

    private AlarmVisit transformSingleGroupedDataVisit(GroupedSyslogData groupedData) {
        try {
            return AlarmVisit.builder()
                    .id(UUID.randomUUID().toString())
                    .createdAt(LocalDateTime.now())
                    .alarmName( groupedData.getOriginEventName())
                    .alarmLevel(convertAlarmLevel(groupedData.getMaxEventLevel()))
                    .alarmType(getAlarmType(groupedData.getFirstEventType(),groupedData.getEventType()))
                    .alarmMajorType(groupedData.getEventType())
                    .alarmMinorType(groupedData.getMinEventType())
                    .alarmAreaId(0)
                    .attackIp(groupedData.getAttackIps())
                    .victimIp(groupedData.getVictimIps())
                    .victimWebUrl(groupedData.getVictimWebUrls())
                    .attackChainPhase(new Integer[]{-1})
                    .deviceId(groupedData.getDeviceIds())
                    .tag(null)
                    .comment(buildComment(groupedData))
                    .originLogIds(groupedData.getOriginLogIds())
                    .queryId(null)
                    .judgedState(0)
                    .disposedState(0)
                    .dispositionAdvice("研判后处置")
                    .attackResult(determineAttackResult(groupedData))
                    .fall(0)
                    .payload(extractPayloadSample(groupedData.getPayloadSamples()))
                    .operateEvent(null)
                    .attackPort(groupedData.getAttackPorts())
                    .victimPort(groupedData.getVictimPorts())
                    .attackMethod(groupedData.getOriginEventName())
                    .businessExt(null)
                    .logStartAt(groupedData.getMinLogTime())
                    .logEndAt(groupedData.getMaxLogTime())
                    .httpStatus(convertHttpStatus(groupedData.getHttpStatusCodes()))
                    .dnsInfo(groupedData.getDnsInfo())
                    .accountInfo(null)
                    .attackerInfo(null)
                    .victimInfo(null)
                    .suspiciousAction(null)
                    .vulnInfo(null)
                    .weakPwd(null)
                    .complianceBaseline(null)
                    .fileInfo(null)
                    .fileTags(null)
                    .endpointInfo(null)
                    .endpointProtection(null)
                    .originInfo(null)
                    .protocolInfo(null)
                    .emailInfo(null)
                    .sensitiveData(null)
                    .hitIntelligence(0)
                    .windowTime(null)
                    .updatedAt(LocalDateTime.now())
                    .engineType(null)
                    .attackIpPic(null)
                    .victimIpPic(null)
                    .operationAt(null)
                    .attackDirection("other")
                    .etlTime(LocalDateTime.now())
                    .logCount(groupedData.getLogCount().intValue())
                    .isAssetHit(0)
                    .focused(false)
                    .baseFocused(false)
                    .isUpdated(false)
                    .httpReqHeader(groupedData.getHttpReqHeaders())
                    .httpReqBody(groupedData.getHttpReqBodys())
                    .httpRespHeader(groupedData.getHttpRespHeaders())
                    .httpRespBody(groupedData.getHttpRespBodys())
                    .reason(null)
                    .dtype(null)
                    .originField(null)
                    .originLog(null)
                    .build();

        } catch (Exception e) {
            log.error("转换分组数据失败: {}", groupedData, e);
            return null;
        }
    }

    private String  getAlarmType(String firstEventType,String eventType) {
        // 如果 firstEventType 有效则使用它
        if (firstEventType != null && !firstEventType.isEmpty()) {
            return firstEventType;
        }

        // 否则使用 eventType（如果也为 null 则返回空字符串）
        return eventType != null ? eventType : "";
    }
    /**
     * 确定attack_result的值
     */
    private Integer determineAttackResult(GroupedSyslogData groupedData) {
        // 优先使用单个attack_result值
        if (groupedData.getAttackResult() != null) {
            return groupedData.getAttackResult();
        }

        // 如果没有单个值，使用最常见的值
        if (groupedData.getMostCommonAttackResult() != null) {
            return groupedData.getMostCommonAttackResult();
        }

        // 如果有多值，取第一个非空值
        if (groupedData.getAllAttackResults() != null && groupedData.getAllAttackResults().length > 0) {
            for (Integer result : groupedData.getAllAttackResults()) {
                if (result != null) {
                    return result;
                }
            }
        }

        // 默认值
        return -1;
    }

    /**
     * 提取payload样本
     */
    private byte[] extractPayloadSample(byte[][] payloadSamples) {
        if (payloadSamples == null || payloadSamples.length == 0) {
            return null;
        }
        // 返回第一个样本
        return payloadSamples[0];
    }

    /**
     * 构建comment字段
     */
    private String buildComment(GroupedSyslogData groupedData) {
        String victimIpsStr;
        if (StringUtils.isNotBlank(groupedData.getVictimIpsStr())) {
            victimIpsStr = groupedData.getVictimIpsStr();
        } else if (groupedData.getVictimIps() != null && groupedData.getVictimIps().length > 0) {
            victimIpsStr = String.join(",", groupedData.getVictimIps());
        } else {
            victimIpsStr = "未知";
        }

        return String.format(
                "24小时内，检测到%s上产生%s告警：\n告警名称：%s\n攻击IP：%s\n攻击结果：%d",
                victimIpsStr,
                convertAlarmLevel(groupedData.getMaxEventLevel()),
                groupedData.getOriginEventName(),
                convertAttackIps(groupedData.getAttackIps()),
                determineAttackResult(groupedData)
        );
    }

    private String convertAlarmLevel(Integer eventLevel) {
        if (eventLevel == null) return "未知";
        switch (eventLevel) {
            case 0: return "安全(无威胁)";
            case 1: return "低危";
            case 2: return "中危";
            case 3: return "高危";
            case 4: return "超危";
            default: return "未知";
        }
    }

    private String convertHttpStatus(String[] httpStatusCodes) {
        if (httpStatusCodes == null || httpStatusCodes.length == 0) {
            return null;
        }
        return String.join(",", httpStatusCodes);
    }

    private String convertAttackIps(String[] attackIps) {
        if (attackIps == null || attackIps.length == 0) {
            return null;
        }
        return String.join(",", attackIps);
    }


}