"""Masking + trust-lane policy engine."""

from __future__ import annotations
from typing import Any, Dict, Iterable

from .attestation import verify_attestation
from .types import DataAttestation, TrustLane


def mask_value(value: str, can_view_pii: bool) -> str:
    """Mask a value if viewer lacks PII access."""
    if can_view_pii:
        return value
    if not value:
        return value
    return "*" * min(len(value), 12)


def is_pii_column(column_name: str) -> bool:
    """Return True when a column name looks like it may contain PII."""
    name = (column_name or "").lower()
    pii_tokens = ("email", "e-mail", "ssn", "social", "phone", "mobile", "dob", "birth", "tax_id")
    return any(token in name for token in pii_tokens)


def mask_row(row: Dict[str, str], can_view_pii: bool) -> Dict[str, str]:
    """Mask PII fields in a row dict when the viewer lacks access."""
    if can_view_pii:
        return row
    masked = {}
    for key, value in row.items():
        if is_pii_column(key):
            masked[key] = mask_value(str(value), can_view_pii=False)
        else:
            masked[key] = value
    return masked


def mask_rows(rows: Iterable[Dict[str, str]], can_view_pii: bool) -> list[Dict[str, str]]:
    """Mask a sequence of row dicts."""
    return [mask_row(r, can_view_pii=can_view_pii) for r in rows]


def resolve_lane(route: str) -> TrustLane:
    """Resolve route name to trust lane."""
    key = (route or "").strip().lower()
    if key in {"client_cortex", "client_cortex_raw", "cortex_raw"}:
        return TrustLane.CLIENT_CORTEX_RAW
    return TrustLane.DATABRIDGE_AI_MASKED


def enforce_attestation(
    attestation: Dict[str, Any] | DataAttestation | None,
    *,
    lane: TrustLane,
    public_key_registry: Dict[str, str],
) -> Dict[str, Any]:
    """Enforce lane-specific attestation requirements.

    Rules:
    - DATABRIDGE_AI_MASKED: valid signature AND masked=True required.
    - CLIENT_CORTEX_RAW: valid signature required; masked may be False.
    """
    if not attestation:
        return {"ok": False, "code": "TRUST_ATTESTATION_MISSING"}

    try:
        obj = attestation if isinstance(attestation, DataAttestation) else DataAttestation(**attestation)
    except Exception:
        return {"ok": False, "code": "TRUST_ATTESTATION_INVALID_FORMAT"}

    verified = verify_attestation(obj, public_key_registry)
    if not verified.get("valid"):
        return {"ok": False, "code": "TRUST_ATTESTATION_INVALID", "reason": verified.get("reason")}

    if obj.lane != lane:
        return {"ok": False, "code": "TRUST_LANE_MISMATCH", "reason": f"{obj.lane.value} != {lane.value}"}

    if lane == TrustLane.DATABRIDGE_AI_MASKED and not obj.masked:
        return {"ok": False, "code": "TRUST_MASK_REQUIRED"}

    return {"ok": True, "code": "OK"}
