"""Vulnerability Snapshot Repository - 漏洞快照数据访问层"""

import logging
from typing import List

from django.db import transaction

from apps.asset.models import VulnerabilitySnapshot
from apps.asset.dtos.snapshot import VulnerabilitySnapshotDTO
from apps.common.decorators import auto_ensure_db_connection
from apps.common.utils import deduplicate_for_bulk

logger = logging.getLogger(__name__)


@auto_ensure_db_connection
class DjangoVulnerabilitySnapshotRepository:
    """漏洞快照仓储（Django ORM 实现）"""

    def save_snapshots(self, items: List[VulnerabilitySnapshotDTO]) -> None:
        """批量保存漏洞快照记录。

        使用 ``ignore_conflicts`` 策略，如果快照已存在则跳过。
        具体唯一约束由数据库模型控制。
        
        注意：会自动按唯一约束字段去重，保留最后一条记录。
        """
        if not items:
            logger.warning("漏洞快照列表为空，跳过保存")
            return

        try:
            # 根据模型唯一约束自动去重
            unique_items = deduplicate_for_bulk(items, VulnerabilitySnapshot)
            
            snapshot_objects = [
                VulnerabilitySnapshot(
                    scan_id=item.scan_id,
                    url=item.url,
                    vuln_type=item.vuln_type,
                    severity=item.severity,
                    source=item.source,
                    cvss_score=item.cvss_score,
                    description=item.description,
                    raw_output=item.raw_output,
                )
                for item in unique_items
            ]

            with transaction.atomic():
                VulnerabilitySnapshot.objects.bulk_create(
                    snapshot_objects,
                    ignore_conflicts=True,
                )

            logger.debug("成功保存 %d 条漏洞快照记录", len(unique_items))

        except Exception as e:
            logger.error(
                "批量保存漏洞快照失败 - 数量: %d, 错误: %s",
                len(items),
                str(e),
                exc_info=True,
            )
            raise

    def get_by_scan(self, scan_id: int):
        """按扫描任务获取漏洞快照 QuerySet。"""
        return VulnerabilitySnapshot.objects.filter(scan_id=scan_id).order_by("-created_at")

    def get_all(self):
        return VulnerabilitySnapshot.objects.all().order_by('-created_at')
