"""Derive exhaustive crash outcomes from changed authoritative artifacts."""

from __future__ import annotations

import hashlib
from pathlib import Path
from typing import ClassVar

from pydantic import BaseModel, ConfigDict

from scripts.nutricoach_v140_golden_path_models import (
    CliError, FaultEvidence, FaultOutcome, StepRequest,
)

_SUCCESS = frozenset({
    "submitted", "missed", "late_submitted", "delivered", "sent_audited", "bound",
    "durable_claim", "durable_fence",
})
_UNKNOWN = frozenset({"unknown"})


class DurableProbe(BaseModel):
    model_config: ClassVar[ConfigDict] = ConfigDict(extra="ignore")

    kst_day: str | None = None
    state: str | None = None
    outcome: str | None = None
    logical_key: str | None = None
    schedule_key: str | None = None
    call_key: str | None = None
    row_digest: str | None = None
    entry_digest: str | None = None
    message_id: str | None = None


def snapshot_lines(root: Path) -> dict[str, int]:
    return {
        path.relative_to(root).as_posix(): len(path.read_text(encoding="utf-8").splitlines())
        for path in root.rglob("*.jsonl") if "boundary-events" not in path.parts
    }


def snapshot_files(root: Path) -> dict[str, str]:
    return {
        path.relative_to(root).as_posix(): hashlib.sha256(path.read_bytes()).hexdigest()
        for path in root.rglob("*") if path.is_file()
    }


def _ledger_suffix(boundary: str) -> str | None:
    if not boundary.startswith("append_fsync:"):
        return None
    return {
        "customer_schedule.py": "scheduled-deliveries.jsonl",
        "nutrition_weekly_operations_ledger_history.py": "weekly-operations-topic59.jsonl",
        "nutrition_weekly_owner_ledger.py": "weekly-draft-generations.jsonl",
        "weekly_operations_store.py": ".day-status-v1.jsonl",
    }.get(boundary.split(":", 2)[1])


def derive_fault_outcome(
    root: Path, before: dict[str, int], prior_files: dict[str, str],
    boundary: str, target: StepRequest,
) -> tuple[FaultOutcome, tuple[FaultEvidence, ...]]:
    suffix = _ledger_suffix(boundary)
    provider_kind = boundary.removeprefix("provider:send:") if boundary.startswith("provider:send:") else None
    if boundary == "provider:edit:topic59":
        provider_kind = "topic59_edit"
    selected: dict[str, FaultEvidence] = {}
    target_day = target.now[:10]
    for path in sorted(root.rglob("*.jsonl")):
        relative = path.relative_to(root).as_posix()
        if "boundary-events" in path.parts or (suffix is not None and not relative.endswith(suffix)):
            continue
        if provider_kind is not None and relative != "provider-transcript.jsonl":
            continue
        for line in path.read_text(encoding="utf-8").splitlines()[before.get(relative, 0):]:
            probe = DurableProbe.model_validate_json(line)
            if probe.kst_day is not None and probe.kst_day != target_day:
                continue
            if provider_kind is not None and not (probe.call_key or "").startswith(provider_kind + ":"):
                continue
            state = probe.state or probe.outcome
            if state not in _SUCCESS | _UNKNOWN:
                continue
            row_id = probe.logical_key or probe.schedule_key or probe.call_key or probe.message_id
            if row_id is None:
                raise CliError(f"fault evidence lacks row identity: {relative}")
            digest = probe.row_digest or probe.entry_digest or hashlib.sha256(line.encode()).hexdigest()
            selected[row_id] = FaultEvidence(
                source=relative, row_id=row_id, row_digest=digest, state=state,
            )
    if not selected and boundary.startswith("append_fsync:customer_schedule.py:"):
        for path in sorted(root.rglob("*")):
            if not path.is_file() or path.suffix in {".lock", ".jsonl"}:
                continue
            relative = path.relative_to(root).as_posix()
            digest = hashlib.sha256(path.read_bytes()).hexdigest()
            if prior_files.get(relative) == digest:
                continue
            state = (
                "durable_claim" if path.suffix == ".claim" and target_day in relative
                else "durable_fence" if path.name == "scheduled-deliveries-fence.json" else None
            )
            if state is not None:
                selected[relative] = FaultEvidence(
                    source=relative, row_id=relative, row_digest=digest, state=state,
                )
    evidence = tuple(selected[key] for key in sorted(selected))
    classes = {item.state in _UNKNOWN for item in evidence}
    if not evidence or len(classes) != 1:
        raise CliError(f"fault outcome is ambiguous: {boundary}")
    outcome = FaultOutcome.TERMINAL_UNKNOWN if True in classes else FaultOutcome.RECONCILED_SUCCESS
    return outcome, evidence