"""Durable transaction phase journal and recovery predicate."""

from __future__ import annotations

import json
from pathlib import Path
from typing import final

from pydantic import JsonValue, TypeAdapter

from scripts.nutricoach_v150_sealed_authority import atomic_write

_OBJECT = TypeAdapter(dict[str, JsonValue])


@final
class PhaseJournal:
    """Persist the last durable transaction phase."""

    def __init__(self, path: Path) -> None:
        self.path = path

    def advance(self, phase: str) -> None:
        payload = (
            json.dumps(
                {"phase": phase, "schema": "nutricoach-v150-phase-journal-v3"},
                sort_keys=True,
                separators=(",", ":"),
            ).encode()
            + b"\n"
        )
        atomic_write(self.path, payload, 0o400)

    def recovery_required(self) -> bool:
        return self.phase() not in {
            None,
            "COMMITTED",
            "ROLLED_BACK",
            "ROLLED_BACK_SAFE_CRON_PAUSED",
        }

    def phase(self) -> str | None:
        """Return the durable phase, if any."""
        if not self.path.is_file():
            return None
        value = _OBJECT.validate_json(self.path.read_bytes())
        phase = value.get("phase")
        return phase if isinstance(phase, str) else None
