#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
SARM SDK 漏洞 API V2版本

提供漏洞相关的API操作，V2版本已移除所有数据校验逻辑，提供更快的数据处理性能。
"""

from typing import List, Dict, Any, Optional, TYPE_CHECKING
from ..models.response import BatchOperationResult

if TYPE_CHECKING:
    from ..client_v2 import SARMClientV2


class VulnerabilityAPI:
    """漏洞API类 V2版本 - 已移除数据校验"""

    def __init__(self, client: 'SARMClientV2'):
        self.client = client

    def create_batch(
        self,
        vulnerabilities: List[Dict[str, Any]]
    ) -> Dict[str, Any]:
        """
        批量创建漏洞(预审)

        该方法会同步:
        1. 漏洞创建/更新
        2. 安全问题创建/更新
        3. 漏洞、安全问题和成分关联关系创建
        4. 安全问题关联载体信息创建
        5. 安全问题关联安全能力信息创建

        Args:
            vulnerabilities: 漏洞数据列表,每个元素格式如下:
                {
                    "vuln_unique_id": "漏洞唯一ID(必填)",
                    "security_capability_unique_id_list": ["cap_id1"],  # 必填
                    "title": "漏洞标题(必填)",
                    "source": "数据来源(必填)",  # 必填, 如 "openApi"
                    "application_unique_id_list": ["app_id1"],  # 可选
                    "carrier_unique_id_list": ["carrier_id1"],  # 可选
                    "component_unique_id_list": ["comp_id1"],  # 可选
                    "description": "漏洞详细描述(可选)",
                    "severity": "漏洞等级(可选)",  # critical/high/medium/low/info
                    "status": "漏洞状态(可选)",  # open/resolved/in progress/closed/false positive/risk accepted
                    "vulnerability_type": "漏洞类别(可选)",
                    "cwe_id": "CWE编号(可选)",
                    "cve_id": "CVE编号(可选)",
                    "tags": ["tag1", "tag2"],  # 可选
                    "vuln_identifiers": [  # 其他漏洞编号(可选)
                        {"type": "类型", "id": "编号"}
                    ],
                    "cvss": [  # CVSS评分信息(可选)
                        {"score": "评分", "vector": "向量", "version": "版本"}
                    ],
                    "impact": "漏洞影响(可选)",
                    "context": [  # 漏洞上下文信息(可选)
                        {"name": "名称", "type": "类型", "content": "内容", "description": "描述"}
                    ],
                    "solution": [  # 修复方案(可选)
                        {"type": "类型", "details": "详情", "description": "描述"}
                    ],
                    "reference": [  # 参考链接(可选)
                        {"type": "类型", "url": "链接"}
                    ],
                    "report_url": "报告URL(可选)",
                    "discovery_at": "发现时间(可选)",
                    "owner_name": "负责人姓名(可选)",
                    "owner_unique_id": "负责人唯一ID(可选)"
                }

        Returns:
            Dict[str, Any]: 批量操作结果

        Note:
            - application_unique_id_list/carrier_unique_id_list/component_unique_id_list
              不传为不操作,如果传了(空列表)就会覆盖原来关联关系

        Example:
            >>> # 示例1: 创建CVE漏洞
            >>> vulnerabilities = [{
            ...     "vuln_unique_id": "CVE-2023-12345",
            ...     "security_capability_unique_id_list": ["cap_001"],
            ...     "title": "Apache Log4j远程代码执行漏洞",
            ...     "source": "openApi",  # 必填
            ...     "description": "Apache Log4j2存在远程代码执行漏洞",
            ...     "severity": "critical",
            ...     "status": "open",
            ...     "vulnerability_type": "远程代码执行",
            ...     "cve_id": "CVE-2023-12345",
            ...     "cwe_id": "CWE-502",
            ...     "component_unique_id_list": ["comp_log4j"],
            ...     "tags": ["rce", "log4j"]
            ... }]
            >>> result = api.create_batch(vulnerabilities)
            >>>
            >>> # 示例2: 创建自定义漏洞并关联载体
            >>> vulnerabilities = [{
            ...     "vuln_unique_id": "CUSTOM-001",
            ...     "security_capability_unique_id_list": ["cap_sast"],
            ...     "title": "SQL注入漏洞",
            ...     "source": "openApi",  # 必填
            ...     "description": "用户登录接口存在SQL注入",
            ...     "severity": "high",
            ...     "status": "in progress",
            ...     "vulnerability_type": "SQL注入",
            ...     "carrier_unique_id_list": ["carrier_api_001"],
            ...     "application_unique_id_list": ["app_user_service"],
            ...     "owner_unique_id": "user_dev_001"
            ... }]
            >>> result = api.create_batch(vulnerabilities)
        """
        # 发送请求到V2预审接口
        response = self.client.post(
            '/api/v2/vuln/temporary/insert',
            data=vulnerabilities
        )
        return response

    def create(
        self,
        vuln_unique_id: str,
        security_capability_unique_id_list: List[str],
        title: str,
        source: str = "openApi",
        application_unique_id_list: Optional[List[str]] = None,
        carrier_unique_id_list: Optional[List[str]] = None,
        component_unique_id_list: Optional[List[str]] = None,
        description: Optional[str] = None,
        severity: Optional[str] = None,
        status: Optional[str] = None,
        vulnerability_type: Optional[str] = None,
        cwe_id: Optional[str] = None,
        cve_id: Optional[str] = None,
        tags: Optional[List[str]] = None,
        vuln_identifiers: Optional[List[Any]] = None,
        cvss: Optional[List[Any]] = None,
        impact: Optional[str] = None,
        context: Optional[List[Any]] = None,
        solution: Optional[List[Any]] = None,
        reference: Optional[List[Any]] = None,
        report_url: Optional[str] = None,
        discovery_at: Optional[str] = None,
        owner_name: Optional[str] = None,
        owner_unique_id: Optional[str] = None
    ) -> Dict[str, Any]:
        """
        创建单个漏洞(预审)

        Args:
            vuln_unique_id: 漏洞唯一ID(必填)
            security_capability_unique_id_list: 安全能力唯一ID列表(必填)
            title: 漏洞标题(必填)
            source: 数据来源(默认"openApi")
            application_unique_id_list: 应用唯一ID列表(可选)
            carrier_unique_id_list: 载体唯一ID列表(可选)
            component_unique_id_list: 成分唯一ID列表(可选)
            description: 漏洞详细描述(可选)
            severity: 漏洞等级(可选) - critical/high/medium/low/info
            status: 漏洞状态(可选) - open/resolved/in progress/closed/false positive/risk accepted
            vulnerability_type: 漏洞类别(可选)
            cwe_id: CWE编号(可选)
            cve_id: CVE编号(可选)
            tags: 标签列表(可选)
            vuln_identifiers: 其他漏洞编号(可选)
            cvss: CVSS评分信息(可选)
            impact: 漏洞影响(可选)
            context: 漏洞上下文信息(可选)
            solution: 修复方案(可选)
            reference: 参考链接(可选)
            report_url: 报告URL(可选)
            discovery_at: 发现时间(可选)
            owner_name: 负责人姓名(可选)
            owner_unique_id: 负责人唯一ID(可选)

        Returns:
            Dict[str, Any]: 操作结果

        Example:
            >>> # 示例1: 创建CVE漏洞
            >>> result = api.create(
            ...     vuln_unique_id="CVE-2023-12345",
            ...     security_capability_unique_id_list=["cap_001"],
            ...     title="Apache Log4j远程代码执行漏洞",
            ...     source="openApi",  # 默认值，可省略
            ...     description="Apache Log4j2存在远程代码执行漏洞",
            ...     severity="critical",
            ...     status="open",
            ...     vulnerability_type="远程代码执行",
            ...     cve_id="CVE-2023-12345",
            ...     cwe_id="CWE-502",
            ...     component_unique_id_list=["comp_log4j"],
            ...     tags=["rce", "log4j"]
            ... )
            >>>
            >>> # 示例2: 最小化创建
            >>> result = api.create(
            ...     vuln_unique_id="CUSTOM-001",
            ...     security_capability_unique_id_list=["cap_sast"],
            ...     title="SQL注入漏洞"
            ... )
        """
        # 构建漏洞数据
        vuln_data = {
            "vuln_unique_id": vuln_unique_id,
            "security_capability_unique_id_list": security_capability_unique_id_list,
            "title": title,
            "source": source  # 必填字段
        }

        # 添加可选字段
        if application_unique_id_list is not None:
            vuln_data["application_unique_id_list"] = application_unique_id_list
        if carrier_unique_id_list is not None:
            vuln_data["carrier_unique_id_list"] = carrier_unique_id_list
        if component_unique_id_list is not None:
            vuln_data["component_unique_id_list"] = component_unique_id_list
        if description:
            vuln_data["description"] = description
        if severity:
            vuln_data["severity"] = severity
        if status:
            vuln_data["status"] = status
        if vulnerability_type:
            vuln_data["vulnerability_type"] = vulnerability_type
        if cwe_id:
            vuln_data["cwe_id"] = cwe_id
        if cve_id:
            vuln_data["cve_id"] = cve_id
        if tags:
            vuln_data["tags"] = tags
        if vuln_identifiers:
            vuln_data["vuln_identifiers"] = vuln_identifiers
        if cvss:
            vuln_data["cvss"] = cvss
        if impact:
            vuln_data["impact"] = impact
        if context:
            vuln_data["context"] = context
        if solution:
            vuln_data["solution"] = solution
        if reference:
            vuln_data["reference"] = reference
        if report_url:
            vuln_data["report_url"] = report_url
        if discovery_at:
            vuln_data["discovery_at"] = discovery_at
        if owner_name:
            vuln_data["owner_name"] = owner_name
        if owner_unique_id:
            vuln_data["owner_unique_id"] = owner_unique_id

        return self.create_batch([vuln_data])

    def update(self, vulnerability_data: Dict[str, Any]) -> Dict[str, Any]:
        """更新漏洞信息"""
        response = self.client.post('/api/vuln/update', data=vulnerability_data)
        return response

    def get_list(
        self,
        page: int = 1,
        limit: int = 50,
        cve_id: str = None,
        cwe_id: str = None,
        title: str = None,
        vuln_union_id: str = None,
        severity: Optional[str] = None,
        status: Optional[str] = None
    ) -> Dict[str, Any]:
        """
        获取漏洞列表

        Args:
            page: 页码
            limit: 每页条数
            cve_id: CVE ID
            cwe_id: CWE ID
            title: 漏洞标题
            vuln_union_id: 漏洞联合ID
            severity: 漏洞严重程度
            status: 漏洞状态

        Returns:
            漏洞列表
        """
        params = {"page": page, "limit": limit}

        # 处理字符串参数
        if cve_id:
            params["cve_id"] = cve_id
        if cwe_id:
            params["cwe_id"] = cwe_id
        if title:
            params["title"] = title
        if vuln_union_id:
            params["vuln_union_id"] = vuln_union_id
        # 处理枚举参数
        if severity:
            params["severity"] = severity
        if status:
            params["status"] = status

        response = self.client.get('/api/vuln/', params=params)
        return response
