"""Unnamed-inode authority marker preparation and durable commit."""

from __future__ import annotations

import errno
import hashlib
import os
import stat
from collections.abc import Callable
from dataclasses import dataclass
from typing import Final

from checkin_cli.weekly_operations import WeeklyOperationsAlreadyInitialized, WeeklyOperationsAuthorityCompromise, WeeklyOperationsCorruption, WeeklyOperationsPlatformNotSupported
from checkin_cli.weekly_operations_layout import MARKER_NAME, validate_customer_inventory
from checkin_cli.weekly_operations_link import link_unnamed_file
from checkin_cli.weekly_operations_parent import WeeklyOperationsParentAuthority

_FILE_FLAGS: Final = os.O_RDONLY | os.O_NOFOLLOW | os.O_CLOEXEC | os.O_NONBLOCK
_UNSUPPORTED: Final = frozenset((errno.ENOSYS, errno.EOPNOTSUPP, errno.EINVAL, errno.EPERM))
FileIdentity = tuple[int, int]
_NO_ENTRIES: Final[frozenset[str]] = frozenset()


@dataclass(frozen=True, slots=True)
class PreparedMarker:
    descriptor: int
    identity: FileIdentity
    payload: bytes
    marker_digest: str


@dataclass(frozen=True, slots=True)
class PublishedMarker:
    marker: os.stat_result
    marker_digest: str


def _identity(info: os.stat_result) -> FileIdentity:
    return info.st_dev, info.st_ino


def _write_all(descriptor: int, payload: bytes) -> None:
    offset = 0
    while offset < len(payload):
        offset += os.write(descriptor, payload[offset:])


def _read_all(descriptor: int) -> bytes:
    _ = os.lseek(descriptor, 0, os.SEEK_SET)
    chunks: list[bytes] = []
    remaining = 4097
    while remaining and (chunk := os.read(descriptor, remaining)):
        chunks.append(chunk)
        remaining -= len(chunk)
    payload = b"".join(chunks)
    if len(payload) > 4096:
        raise WeeklyOperationsAuthorityCompromise("authority marker exceeds bounded size")
    return payload


def _safe_marker(info: os.stat_result, *, links: int) -> bool:
    return stat.S_ISREG(info.st_mode) and stat.S_IMODE(info.st_mode) == 0o600 and info.st_uid == os.geteuid() and info.st_nlink == links


def _read_named(directory: int) -> tuple[os.stat_result, bytes]:
    try:
        descriptor = os.open(MARKER_NAME, _FILE_FLAGS, dir_fd=directory)
    except OSError as error:
        raise WeeklyOperationsAuthorityCompromise("authority marker name is unsafe") from error
    try:
        info = os.fstat(descriptor)
        named = os.stat(MARKER_NAME, dir_fd=directory, follow_symlinks=False)
        payload = _read_all(descriptor)
        if not _safe_marker(info, links=1) or _identity(info) != _identity(named):
            raise WeeklyOperationsAuthorityCompromise("authority marker identity changed")
        return info, payload
    finally:
        os.close(descriptor)


class MarkerNameOccupied(WeeklyOperationsCorruption):
    """Descriptor link found a marker name requiring unmasked classification."""


def classify_existing_marker(directory: int, canonical: Callable[[bytes], bool]) -> None:
    info, payload = _read_named(directory)
    if not _safe_marker(info, links=1) or not canonical(payload):
        raise WeeklyOperationsAuthorityCompromise("authority marker is preoccupied")
    try:
        validate_customer_inventory(directory)
    except WeeklyOperationsCorruption as error:
        raise WeeklyOperationsAuthorityCompromise("existing authority inventory is unsafe") from error
    raise WeeklyOperationsAlreadyInitialized("already_initialized")


def _require_empty(
    directory: int, canonical: Callable[[bytes], bool], allowed: frozenset[str]
) -> None:
    entries = frozenset(os.listdir(directory))
    if entries == allowed:
        return
    if MARKER_NAME in entries:
        classify_existing_marker(directory, canonical)
    raise WeeklyOperationsCorruption("uninitialized authority directory is not empty")


def reconcile_owned_marker(directory: int, expected: FileIdentity, payload: bytes) -> os.stat_result:
    info, observed = _read_named(directory)
    if _identity(info) != expected or observed != payload:
        raise WeeklyOperationsAuthorityCompromise("published marker does not match unnamed inode")
    return info


def prepare_authority_marker(
    parent: WeeklyOperationsParentAuthority, payload: bytes,
    canonical: Callable[[bytes], bool], *, allowed: frozenset[str] = _NO_ENTRIES,
) -> PreparedMarker:
    """Create and validate a complete unnamed marker inode."""
    parent.verify()
    _require_empty(parent.descriptor, canonical, allowed)
    try:
        temporary = os.open(".", os.O_TMPFILE | os.O_RDWR | os.O_CLOEXEC, 0o600, dir_fd=parent.descriptor)
    except OSError as error:
        if error.errno in _UNSUPPORTED:
            raise WeeklyOperationsPlatformNotSupported("O_TMPFILE authority publication is unsupported") from error
        raise WeeklyOperationsCorruption("unnamed authority marker creation failed") from error
    try:
        _write_all(temporary, payload)
        os.fsync(temporary)
        temporary_info = os.fstat(temporary)
        if not _safe_marker(temporary_info, links=0):
            raise WeeklyOperationsAuthorityCompromise("unnamed authority marker is unsafe")
        return PreparedMarker(temporary, _identity(temporary_info), payload, hashlib.sha256(payload).hexdigest())
    except (OSError, WeeklyOperationsCorruption, KeyboardInterrupt, SystemExit):
        os.close(temporary)
        raise


def commit_authority_marker(parent: WeeklyOperationsParentAuthority, prepared: PreparedMarker) -> PublishedMarker:
    """Link, directory-fsync, and reconcile; SIGKILL/power loss before fsync stays ambiguous."""
    try:
        link_unnamed_file(prepared.descriptor, parent.descriptor, MARKER_NAME)
    except FileExistsError as error:
        raise MarkerNameOccupied("authority marker name is occupied") from error
    except WeeklyOperationsCorruption:
        raise
    except OSError as error:
        try:
            _ = reconcile_owned_marker(parent.descriptor, prepared.identity, prepared.payload)
        except WeeklyOperationsCorruption:
            raise WeeklyOperationsCorruption("descriptor marker link failed") from error
    try:
        os.fsync(parent.descriptor)
    except OSError as error:
        raise WeeklyOperationsCorruption("authority directory fsync failed") from error
    marker = reconcile_owned_marker(parent.descriptor, prepared.identity, prepared.payload)
    return PublishedMarker(marker, prepared.marker_digest)
