"""
Atomic write utilities for receipt chain persistence.

Provides POSIX-compliant atomic file writes with fsync guarantees for
crash-safe manifest and staged file commits.
"""

from __future__ import annotations

import json
import os
import tempfile
from pathlib import Path
from typing import Any, Dict


def atomic_write_json(path: Path, payload: Dict[str, Any]) -> None:
    """
    Atomically write a JSON payload to disk with fsync guarantees.

    This ensures:
    - Atomic replacement via os.replace (POSIX)
    - Durable commit via fsync on file + parent directory
    - JCS-style canonical JSON serialization (sorted keys, compact)

    Args:
        path: Target file path for the JSON payload
        payload: Dictionary to serialize as JSON

    Raises:
        OSError: If file operations fail (permissions, disk full, etc.)
    """
    path.parent.mkdir(parents=True, exist_ok=True)

    # Write to temporary file in the same directory (required for atomic os.replace)
    with tempfile.NamedTemporaryFile(
        mode="w",
        dir=path.parent,
        delete=False,
        prefix=".tmp_",
        suffix=".json",
    ) as tmp:
        # JCS-ish: compact, sorted keys for canonical representation
        tmp.write(json.dumps(payload, separators=(",", ":"), sort_keys=True))
        tmp.flush()
        os.fsync(tmp.fileno())
        tmp_path = Path(tmp.name)

    # Atomic rename (POSIX guarantees atomicity)
    os.replace(tmp_path, path)

    # fsync parent directory to persist the rename operation
    dir_fd = os.open(path.parent, os.O_DIRECTORY)
    try:
        os.fsync(dir_fd)
    finally:
        os.close(dir_fd)


__all__ = ["atomic_write_json"]
