package cd.casic.ci.process.process.converter;

import cd.casic.ci.process.dto.resp.ScaVulInfoResp;
import cd.casic.ci.process.process.dataObject.volumnInfo.VulInfo;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
import org.mapstruct.Named;
import org.mapstruct.factory.Mappers;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
@Mapper(componentModel = "spring")
public interface VulInfoConverter {

    VulInfoConverter INSTANCE = Mappers.getMapper(VulInfoConverter.class);

    /**
     * JSON数据转换为数据库实体
     */
    @Mappings({
            @Mapping(target = "id", ignore = true),
            @Mapping(target = "createTime", source = "releaseDate", qualifiedByName = "dateToDateTime"),
            @Mapping(target = "modifyTime", source = "updateDate", qualifiedByName = "dateToDateTime"),
            @Mapping(target = "verifyStatus", source = "auditStatus"),
            @Mapping(target = "vulId", source = "vulUid"),
            @Mapping(target = "isOpenSource", ignore = true),
            @Mapping(target = "vulTitle", source = "vulName"),
            @Mapping(target = "vulDescription", source = "vulDescription"),
            @Mapping(target = "severity", source = "securityLevel", qualifiedByName = "securityLevelToSeverity"),
            @Mapping(target = "solution", source = "suggestion"),
            @Mapping(target = "relieve", ignore = true),
            @Mapping(target = "targetName", source = "influenceComponent"),
            @Mapping(target = "cwes", source = "cwe", qualifiedByName = "cweToCwes"),
            @Mapping(target = "level", source = "isExploit", qualifiedByName = "exploitToLevel"),
            @Mapping(target = "targetType", ignore = true),
            @Mapping(target = "targetUrl", ignore = true),
            @Mapping(target = "affectProjectId", ignore = true),
            @Mapping(target = "unaffectedVersions", ignore = true),
            @Mapping(target = "affectProductName", source = "influenceComponent")
    })
    VulInfo scaToVulInfo(ScaVulInfoResp vulJsonData);

    List<VulInfo> scaToVulInfo(List<ScaVulInfoResp> vulJsonData);
    /**
     * 数据库实体转换为JSON数据
     */
    @Mappings({
            @Mapping(target = "vulUid", source = "vulId"),
            @Mapping(target = "cve", ignore = true),
            @Mapping(target = "cnnvd", ignore = true),
            @Mapping(target = "cnvd", ignore = true),
            @Mapping(target = "cwe", source = "cwes", qualifiedByName = "cwesToCwe"),
            @Mapping(target = "vulName", source = "vulTitle"),
            @Mapping(target = "vulType", ignore = true),
            @Mapping(target = "attackType", ignore = true),
            @Mapping(target = "isExploit", source = "level", qualifiedByName = "levelToExploit"),
            @Mapping(target = "securityLevel", source = "severity", qualifiedByName = "severityToSecurityLevel"),
            @Mapping(target = "cvss4", ignore = true),
            @Mapping(target = "releaseDate", source = "createTime", qualifiedByName = "dateTimeToDate"),
            @Mapping(target = "updateDate", source = "modifyTime", qualifiedByName = "dateTimeToDate"),
            @Mapping(target = "vulDescription", source = "vulDescription"),
            @Mapping(target = "suggestion", source = "solution"),
            @Mapping(target = "detectionTime", ignore = true),
            @Mapping(target = "influenceComponentNum", ignore = true),
            @Mapping(target = "influencePackageNum", ignore = true),
            @Mapping(target = "influenceComponent", source = "targetName"),
            @Mapping(target = "influenceComponentImage", source = "targetName"),
            @Mapping(target = "vulStatus", ignore = true),
            @Mapping(target = "auditStatus", source = "verifyStatus"),
            @Mapping(target = "reachTypeStr", ignore = true),
            @Mapping(target = "fixAvailable", ignore = true),
            @Mapping(target = "isHide", ignore = true),
            @Mapping(target = "cvss2", ignore = true),
            @Mapping(target = "cvss3", ignore = true)
    })
    ScaVulInfoResp vulInfoToSca(VulInfo vulInfo);

    /**
     * LocalDate转换为LocalDateTime
     */
    @Named("dateToDateTime")
    default LocalDateTime dateToDateTime(LocalDate date) {
        if (date == null) {
            return LocalDateTime.now();
        }
        return date.atStartOfDay();
    }

    /**
     * LocalDateTime转换为LocalDate
     */
    @Named("dateTimeToDate")
    default LocalDate dateTimeToDate(LocalDateTime dateTime) {
        if (dateTime == null) {
            return LocalDate.now();
        }
        return dateTime.toLocalDate();
    }

    /**
     * CWE转换为CWE列表
     */
    @Named("cweToCwes")
    default List<String> cweToCwes(String cwe) {
        if (cwe == null || cwe.trim().isEmpty()) {
            return Arrays.asList();
        }
        return Arrays.asList(cwe.split(","));
    }

    /**
     * CWE列表转换为CWE字符串
     */
    @Named("cwesToCwe")
    default String cwesToCwe(List<String> cwes) {
        if (cwes == null || cwes.isEmpty()) {
            return "";
        }
        return String.join(",", cwes);
    }

    /**
     * 利用难度转换为利用级别
     */
    @Named("exploitToLevel")
    default Boolean exploitToLevel(String isExploit) {
        if (isExploit == null) {
            return false;
        }
        // 映射规则：容易 -> true, 困难 -> false, 一般 -> true
        switch (isExploit) {
            case "容易":
            case "一般":
                return true;
            case "困难":
            default:
                return false;
        }
    }

    /**
     * 利用级别转换为利用难度
     */
    @Named("levelToExploit")
    default String levelToExploit(Boolean level) {
        if (level == null) {
            return "困难";
        }
        return level ? "容易" : "困难";
    }

    /**
     * 安全等级转换为危险等级
     */
    @Named("securityLevelToSeverity")
    default Integer securityLevelToSeverity(String securityLevel) {
        if (securityLevel == null) {
            return 0;
        }
        // 映射规则：严重 -> 1, 高危 -> 2, 中危 -> 3, 低危 -> 4
        switch (securityLevel) {
            case "严重":
                return 1;
            case "高危":
                return 2;
            case "中危":
                return 3;
            case "低危":
                return 4;
            default:
                return 0;
        }
    }

    /**
     * 危险等级转换为安全等级
     */
    @Named("severityToSecurityLevel")
    default String severityToSecurityLevel(Integer severity) {
        if (severity == null) {
            return "未知";
        }
        // 映射规则：1 -> 严重, 2 -> 高危, 3 -> 中危, 4 -> 低危
        switch (severity) {
            case 1:
                return "严重";
            case 2:
                return "高危";
            case 3:
                return "中危";
            case 4:
                return "低危";
            default:
                return "未知";
        }
    }
}
