"""Severity model (R-7).

A single authoritative table maps each finding type to a severity. Detectors set
the type; severity is resolved here so the mapping is testable in one place and the
rest of the code never hardcodes a level.

R-7 specifies:
  critical: private keys, SSN, account/routing, card
  high:     frame-detected name, DOB, privilege banner, tracked changes, comments
  medium:   phone, email, address, case number, author and software metadata
  low:      other

Types not named in R-7 are assigned a documented default (logged in build-log.md):
  - ein -> high (a tax identifier; mapping it low would under-warn).
  - non-private-key secrets (aws key, github/slack token, high-entropy assignment)
    -> critical (a leaked live credential is at least as severe as a private key).
"""
from __future__ import annotations

from .models import Severity

SEVERITY_BY_TYPE: dict[str, Severity] = {
    # --- critical ---
    "private_key": Severity.CRITICAL,
    "ssn": Severity.CRITICAL,
    "bank_account": Severity.CRITICAL,
    "routing_number": Severity.CRITICAL,
    "payment_card": Severity.CRITICAL,
    "aws_access_key": Severity.CRITICAL,  # default: leaked credential
    "github_token": Severity.CRITICAL,    # default: leaked credential
    "slack_token": Severity.CRITICAL,     # default: leaked credential
    "generic_secret": Severity.CRITICAL,  # default: leaked credential
    # --- high ---
    "person_name": Severity.HIGH,
    "entity_name": Severity.HIGH,
    "dob": Severity.HIGH,
    "ein": Severity.HIGH,                  # default: tax identifier
    "privilege_banner": Severity.HIGH,
    # R-5 requires every banner variant (privilege and confidentiality) at severity high.
    "confidentiality_banner": Severity.HIGH,
    "tracked_change": Severity.HIGH,
    "comment": Severity.HIGH,
    # Precise photo geolocation; default to high (a client's coordinates are a real harm).
    "exif_gps": Severity.HIGH,
    # --- medium ---
    "phone": Severity.MEDIUM,
    "email": Severity.MEDIUM,
    "address": Severity.MEDIUM,
    "case_number": Severity.MEDIUM,
    "author_metadata": Severity.MEDIUM,
    "software_metadata": Severity.MEDIUM,
}

DEFAULT_SEVERITY = Severity.LOW


def severity_for(finding_type: str) -> Severity:
    return SEVERITY_BY_TYPE.get(finding_type, DEFAULT_SEVERITY)
