from __future__ import annotations

from dataclasses import dataclass, field
from pathlib import Path
import tomllib

from supersonar.models import Severity


DEFAULT_EXCLUDES = [".git", ".venv", "venv", "build", "dist", "__pycache__"]


@dataclass(slots=True)
class ScanConfig:
    exclude: list[str] = field(default_factory=lambda: DEFAULT_EXCLUDES.copy())
    coverage_xml: str | None = None


@dataclass(slots=True)
class QualityGateConfig:
    fail_on: Severity | None = None
    max_issues: int | None = None
    max_low: int | None = None
    max_medium: int | None = None
    max_high: int | None = None
    max_critical: int | None = None
    min_coverage: float | None = None


@dataclass(slots=True)
class ReportConfig:
    output_format: str = "json"
    out: str | None = None


@dataclass(slots=True)
class Config:
    scan: ScanConfig = field(default_factory=ScanConfig)
    quality_gate: QualityGateConfig = field(default_factory=QualityGateConfig)
    report: ReportConfig = field(default_factory=ReportConfig)


def load_config(path: str | None) -> Config:
    if path is None:
        default = Path("supersonar.toml")
        if not default.exists():
            return Config()
        path = str(default)

    cfg_path = Path(path)
    if not cfg_path.exists():
        raise FileNotFoundError(f"Config file not found: {cfg_path}")

    with cfg_path.open("rb") as fh:
        payload = tomllib.load(fh)

    scan = payload.get("scan", {})
    quality_gate = payload.get("quality_gate", {})
    report = payload.get("report", {})

    config = Config()
    config.scan.exclude = list(scan.get("exclude", config.scan.exclude))
    config.scan.coverage_xml = scan.get("coverage_xml")
    config.quality_gate.fail_on = quality_gate.get("fail_on")
    config.quality_gate.max_issues = quality_gate.get("max_issues")
    config.quality_gate.max_low = quality_gate.get("max_low")
    config.quality_gate.max_medium = quality_gate.get("max_medium")
    config.quality_gate.max_high = quality_gate.get("max_high")
    config.quality_gate.max_critical = quality_gate.get("max_critical")
    config.quality_gate.min_coverage = quality_gate.get("min_coverage")
    config.report.output_format = report.get("format", config.report.output_format)
    config.report.out = report.get("out")
    return config
