from __future__ import annotations

from dataclasses import dataclass, field
from enum import Enum
from pathlib import Path
from typing import Any


class Severity(str, Enum):
    CRITICAL = "critical"
    HIGH = "high"
    MEDIUM = "medium"
    LOW = "low"
    INFO = "info"


@dataclass(slots=True)
class PyPIRelease:
    version: str
    upload_time: str
    yanked: bool = False


@dataclass(slots=True)
class PackageMetadata:
    author: str | None = None
    author_email: str | None = None
    maintainer: str | None = None
    maintainer_email: str | None = None
    home_page: str | None = None
    project_urls: dict[str, str] = field(default_factory=dict)
    summary: str | None = None
    license: str | None = None
    # PyPI release history (oldest first)
    release_history: list[PyPIRelease] = field(default_factory=list)
    # Maintainers/owners listed on PyPI
    maintainers: list[str] = field(default_factory=list)


@dataclass(slots=True)
class PackageInfo:
    name: str
    version: str
    source_path: Path
    files: dict[str, str] = field(default_factory=dict)
    metadata: PackageMetadata = field(default_factory=PackageMetadata)
    is_transitive: bool = False
    required_by: list[str] = field(default_factory=list)


@dataclass(slots=True)
class Finding:
    severity: Severity
    title: str
    description: str
    layer: str
    package: str
    version: str
    evidence: dict[str, Any]
    confidence: float
    file: str | None = None
    line: int | None = None
    category: str = "general"
    cve_id: str | None = None
    remediation: str | None = None


@dataclass(slots=True)
class ScanResult:
    package: PackageInfo
    findings: list[Finding]
    risk_score: float
    risk_label: Severity
    layers_run: list[str]
    scan_duration_ms: int
    ai_verdict: str | None = None
    ai_confidence: float | None = None
    cached: bool = False
    scan_id: str = ""

