"""ScoringWeights — validated immutable weight set for the scoring engine.

Enforces that all five weights are non-negative and sum to exactly 100.
"""

from __future__ import annotations

from dataclasses import dataclass


@dataclass(frozen=True, slots=True)
class ScoringWeights:
    """Five scoring dimension weights that must sum to 100."""

    tests: float
    detection_rules: float
    d3fend: float
    recency: float
    severity: float

    def __post_init__(self) -> None:
        fields = [
            self.tests,
            self.detection_rules,
            self.d3fend,
            self.recency,
            self.severity,
        ]
        for f in fields:
            if f < 0:
                raise ValueError("Scoring weights must be non-negative")

        total = sum(fields)
        if abs(total - 100) > 0.01:
            raise ValueError(
                f"Scoring weights must sum to 100, got {total}"
            )

    @classmethod
    def default(cls) -> ScoringWeights:
        """Return the default weight distribution."""
        return cls(
            tests=40.0,
            detection_rules=25.0,
            d3fend=15.0,
            recency=10.0,
            severity=10.0,
        )

    # Backward-compatible aliases for older API payloads
    @property
    def freshness(self) -> float:
        return self.recency

    @property
    def platform_diversity(self) -> float:
        return self.severity
