"""Durable one-use approval and post-stop snapshot authority."""

from __future__ import annotations

import hashlib
import json
import os
import stat
import tempfile
from dataclasses import dataclass
from pathlib import Path
from typing import Literal, final

from scripts.nutricoach_v150_live_models import (
    CANDIDATE_DIGEST,
    ApprovalAlreadyUsed,
    TransactionError,
)


def digest(payload: bytes) -> str:
    """Return one lowercase SHA-256 digest."""
    return hashlib.sha256(payload).hexdigest()


def file_digest(path: Path) -> str:
    """Digest one exact file."""
    return digest(path.read_bytes())


def _sync_directory(path: Path) -> None:
    descriptor = os.open(path, os.O_RDONLY | os.O_DIRECTORY)
    try:
        os.fsync(descriptor)
    finally:
        os.close(descriptor)


def atomic_write(path: Path, payload: bytes, mode: int) -> None:
    """Atomically replace and durably sync one file."""
    descriptor, temporary_text = tempfile.mkstemp(
        prefix=f".{path.name}.", dir=path.parent
    )
    temporary = Path(temporary_text)
    try:
        with os.fdopen(descriptor, "wb") as stream:
            _ = stream.write(payload)
            stream.flush()
            os.fsync(stream.fileno())
        temporary.chmod(mode)
        os.replace(temporary, path)
        _sync_directory(path.parent)
    finally:
        temporary.unlink(missing_ok=True)


@final
class ApprovalLedger:
    """Durably reserve and consume one sealed approval."""

    def __init__(self, root: Path) -> None:
        self._root = root
        self._reserved = root / "authorization-reserved.json"
        self._consumed = root / "authorization-consumed.json"

    def reserve(self) -> None:
        """Exclusively reserve authority before the stop boundary."""
        self._root.mkdir(parents=True, mode=0o700, exist_ok=True)
        if self._consumed.exists():
            raise ApprovalAlreadyUsed("authorization_already_used")
        payload = (
            json.dumps(
                {"candidate_digest": CANDIDATE_DIGEST, "status": "RESERVED"},
                sort_keys=True,
                separators=(",", ":"),
            ).encode()
            + b"\n"
        )
        try:
            descriptor = os.open(
                self._reserved,
                os.O_CREAT | os.O_EXCL | os.O_WRONLY,
                0o400,
            )
        except FileExistsError as exc:
            raise ApprovalAlreadyUsed("authorization_already_reserved") from exc
        with os.fdopen(descriptor, "wb") as stream:
            _ = stream.write(payload)
            stream.flush()
            os.fsync(stream.fileno())
        _sync_directory(self._root)

    def consume(self, outcome: Literal["FAILED", "SUCCEEDED"]) -> None:
        """Irreversibly consume a reserved authority after one attempt."""
        if self._consumed.exists():
            return
        payload = (
            json.dumps(
                {
                    "candidate_digest": CANDIDATE_DIGEST,
                    "outcome": outcome,
                    "status": "CONSUMED",
                },
                sort_keys=True,
                separators=(",", ":"),
            ).encode()
            + b"\n"
        )
        atomic_write(self._consumed, payload, 0o400)
        self._reserved.unlink(missing_ok=True)
        _sync_directory(self._root)


@dataclass(frozen=True, slots=True)
class SnapshotEntry:
    """One exact post-stop rollback entry."""

    path: Path
    snapshot: Path
    digest: str
    mode: int


@dataclass(frozen=True, slots=True)
class SnapshotAuthority:
    """Durable post-stop snapshot set."""

    entries: tuple[SnapshotEntry, ...]
    manifest_digest: str


def capture(paths: tuple[Path, ...], root: Path) -> SnapshotAuthority:
    """Durably capture rollback bytes only after confirmed stop."""
    snapshots = root / "post-stop-snapshots"
    snapshots.mkdir(mode=0o700)
    entries: list[SnapshotEntry] = []
    manifest: list[dict[str, str | int]] = []
    for ordinal, path in enumerate(paths):
        info = path.stat(follow_symlinks=False)
        if path.is_symlink() or not stat.S_ISREG(info.st_mode) or info.st_nlink != 1:
            raise TransactionError("unsafe_snapshot_source")
        payload = path.read_bytes()
        snapshot = snapshots / f"{ordinal:04d}.snapshot"
        atomic_write(snapshot, payload, 0o400)
        entry = SnapshotEntry(
            path, snapshot, digest(payload), stat.S_IMODE(info.st_mode)
        )
        entries.append(entry)
        manifest.append({
            "digest": entry.digest,
            "mode": entry.mode,
            "ordinal": ordinal,
            "path": str(path),
        })
    manifest_payload = (
        json.dumps(manifest, sort_keys=True, separators=(",", ":")).encode() + b"\n"
    )
    atomic_write(snapshots / "snapshot-manifest.json", manifest_payload, 0o400)
    return SnapshotAuthority(tuple(entries), f"sha256:{digest(manifest_payload)}")


def restore(authority: SnapshotAuthority) -> None:
    """Restore every exact byte and mode from durable authority."""
    for entry in authority.entries:
        payload = entry.snapshot.read_bytes()
        if digest(payload) != entry.digest:
            raise TransactionError("snapshot_drift")
        atomic_write(entry.path, payload, entry.mode)
