"""Caller-held dedicated authority-root capability."""

from __future__ import annotations

import fcntl
import hashlib
import json
import os
import stat
from collections.abc import Generator
from contextlib import contextmanager
from dataclasses import dataclass, replace
from pathlib import Path
from typing import ClassVar, Final, NewType

from pydantic import BaseModel, ConfigDict, ValidationError

from checkin_cli.weekly_operations import WeeklyOperationsAuthorityCompromise, WeeklyOperationsCorruption
from checkin_cli.weekly_operations_layout import LAYOUT_DIGEST, MARKER_NAME, ROOT_INVENTORY_DIGEST

PARENT_SCHEMA: Final = "nutricoach-weekly-operations-parent-authority-v2"
_DIRECTORY_FLAGS: Final = os.O_RDONLY | os.O_DIRECTORY | os.O_NOFOLLOW | os.O_CLOEXEC


@dataclass(frozen=True, slots=True)
class WeeklyOperationsParentBinding:
    schema_version: str
    device: int
    inode: int
    mode: int
    owner: int
    links: int
    binding_digest: str


@dataclass(frozen=True, slots=True)
class WeeklyOperationsParentAuthority:
    """Pinned descriptor for the pre-existing dedicated authority directory."""

    descriptor: int
    binding: WeeklyOperationsParentBinding
    acquisition_path: Path

    @property
    def observed_path(self) -> Path:
        return self.acquisition_path

    def verify(self) -> None:
        validate_parent_binding(self.binding)
        info = os.fstat(self.descriptor)
        observed = info.st_dev, info.st_ino, stat.S_IMODE(info.st_mode), info.st_uid, info.st_nlink
        expected = self.binding.device, self.binding.inode, self.binding.mode, self.binding.owner, self.binding.links
        if not stat.S_ISDIR(info.st_mode) or observed != expected:
            raise WeeklyOperationsAuthorityCompromise("authority root identity drift")

    @contextmanager
    def locked(self) -> Generator[None]:
        fcntl.flock(self.descriptor, fcntl.LOCK_EX)
        try:
            yield
        finally:
            fcntl.flock(self.descriptor, fcntl.LOCK_UN)

    def close(self) -> None:
        os.close(self.descriptor)


def _binding_payload(binding: WeeklyOperationsParentBinding) -> bytes:
    value = {field: getattr(binding, field) for field in binding.__dataclass_fields__ if field != "binding_digest"}
    return json.dumps(value, sort_keys=True, separators=(",", ":")).encode()


def validate_parent_binding(binding: WeeklyOperationsParentBinding) -> None:
    expected = hashlib.sha256(_binding_payload(binding)).hexdigest()
    if binding.schema_version != PARENT_SCHEMA or binding.binding_digest != expected or binding.mode != 0o700 or binding.owner != os.geteuid() or binding.links != 2:
        raise WeeklyOperationsCorruption("authority root caller binding is invalid")


def _open_directory(path: Path) -> tuple[int, Path]:
    absolute = path.absolute()
    descriptor = os.open(absolute.anchor, _DIRECTORY_FLAGS)
    try:
        for component in absolute.parts[1:]:
            child = os.open(component, _DIRECTORY_FLAGS, dir_fd=descriptor)
            os.close(descriptor)
            descriptor = child
    except OSError as error:
        os.close(descriptor)
        raise WeeklyOperationsAuthorityCompromise("authority bootstrap path is unsafe") from error
    return descriptor, absolute


def _binding(info: os.stat_result) -> WeeklyOperationsParentBinding:
    provisional = WeeklyOperationsParentBinding(PARENT_SCHEMA, info.st_dev, info.st_ino, stat.S_IMODE(info.st_mode), info.st_uid, info.st_nlink, "")
    return replace(provisional, binding_digest=hashlib.sha256(_binding_payload(provisional)).hexdigest())


def acquire_parent_authority(authority_path: Path) -> WeeklyOperationsParentAuthority:
    """Acquire a pre-existing dedicated authority directory by no-follow path."""
    descriptor, acquisition_path = _open_directory(authority_path)
    try:
        fcntl.flock(descriptor, fcntl.LOCK_EX)
        try:
            info = os.fstat(descriptor)
            binding = _binding(info)
            validate_parent_binding(binding)
            return WeeklyOperationsParentAuthority(descriptor, binding, acquisition_path)
        finally:
            fcntl.flock(descriptor, fcntl.LOCK_UN)
    except WeeklyOperationsCorruption:
        os.close(descriptor)
        raise


def acquire_parent_authority_descriptor(
    descriptor: int, acquisition_path: Path
) -> WeeklyOperationsParentAuthority:
    """Acquire an independently owned capability from a pinned directory fd."""
    owned = os.dup(descriptor)
    try:
        fcntl.flock(owned, fcntl.LOCK_EX)
        try:
            binding = _binding(os.fstat(owned))
            validate_parent_binding(binding)
            return WeeklyOperationsParentAuthority(owned, binding, acquisition_path)
        finally:
            fcntl.flock(owned, fcntl.LOCK_UN)
    except WeeklyOperationsCorruption:
        os.close(owned)
        raise


def reacquire_parent_authority(authority_path: Path, expected: WeeklyOperationsParentBinding) -> WeeklyOperationsParentAuthority:
    """Reacquire only the caller-bound dedicated authority inode."""
    validate_parent_binding(expected)
    descriptor, acquisition_path = _open_directory(authority_path)
    try:
        info = os.fstat(descriptor)
        observed = info.st_dev, info.st_ino, stat.S_IMODE(info.st_mode), info.st_uid, info.st_nlink
        wanted = expected.device, expected.inode, expected.mode, expected.owner, expected.links
        if not stat.S_ISDIR(info.st_mode) or observed != wanted:
            raise WeeklyOperationsAuthorityCompromise("authority bootstrap binding mismatch")
        return WeeklyOperationsParentAuthority(descriptor, expected, acquisition_path)
    except WeeklyOperationsCorruption:
        os.close(descriptor)
        raise


AUTHORITY_SCHEMA: Final = "nutricoach-weekly-operations-authority-v2"
BINDING_SCHEMA: Final = "nutricoach-weekly-operations-authority-binding-v3"
AuthorityId = NewType("AuthorityId", str)


class AuthorityMarker(BaseModel):
    model_config: ClassVar[ConfigDict] = ConfigDict(frozen=True, extra="forbid", strict=True)
    authority_id: str
    schema_version: str
    registry_device: int
    registry_inode: int
    registry_mode: int
    registry_owner: int
    registry_links: int
    registry_digest: str
    root_inventory_digest: str
    layout_digest: str


@dataclass(frozen=True, slots=True)
class WeeklyOperationsAuthorityBinding:
    schema_version: str
    authority_id: AuthorityId
    root_device: int
    root_inode: int
    root_mode: int
    root_owner: int
    root_links: int
    marker_device: int
    marker_inode: int
    marker_mode: int
    marker_owner: int
    marker_links: int
    marker_digest: str
    registry_device: int
    registry_inode: int
    registry_mode: int
    registry_owner: int
    registry_links: int
    registry_digest: str
    root_inventory_digest: str
    layout_digest: str
    binding_digest: str


def _authority_binding_payload(binding: WeeklyOperationsAuthorityBinding) -> bytes:
    value = {field: getattr(binding, field) for field in binding.__dataclass_fields__ if field != "binding_digest"}
    return json.dumps(value, sort_keys=True, separators=(",", ":")).encode()


def validate_authority_binding(binding: WeeklyOperationsAuthorityBinding) -> None:
    expected = hashlib.sha256(_authority_binding_payload(binding)).hexdigest()
    safe = binding.root_mode == 0o700 and binding.root_owner == os.geteuid() and binding.root_links == 2 and binding.marker_mode == 0o600 and binding.marker_owner == os.geteuid() and binding.marker_links == 1 and binding.registry_mode == 0o600 and binding.registry_owner == os.geteuid() and binding.registry_links == 1 and binding.registry_digest == hashlib.sha256(b"").hexdigest()
    if binding.schema_version != BINDING_SCHEMA or binding.binding_digest != expected or binding.root_inventory_digest != ROOT_INVENTORY_DIGEST or binding.layout_digest != LAYOUT_DIGEST or not safe:
        raise WeeklyOperationsCorruption("authority caller binding is invalid")


def construct_authority_binding(authority_id: AuthorityId, root: os.stat_result, marker: os.stat_result, marker_digest: str, registry: os.stat_result, registry_digest: str) -> WeeklyOperationsAuthorityBinding:
    provisional = WeeklyOperationsAuthorityBinding(
        BINDING_SCHEMA, authority_id, root.st_dev, root.st_ino, stat.S_IMODE(root.st_mode), root.st_uid, root.st_nlink,
        marker.st_dev, marker.st_ino, stat.S_IMODE(marker.st_mode), marker.st_uid, marker.st_nlink, marker_digest,
        registry.st_dev, registry.st_ino, stat.S_IMODE(registry.st_mode), registry.st_uid, registry.st_nlink, registry_digest,
        ROOT_INVENTORY_DIGEST, LAYOUT_DIGEST, "",
    )
    return replace(provisional, binding_digest=hashlib.sha256(_authority_binding_payload(provisional)).hexdigest())


def _marker_bytes(marker: AuthorityMarker) -> bytes:
    return (json.dumps(marker.model_dump(mode="json"), sort_keys=True, separators=(",", ":")) + "\n").encode()


def authority_marker_bytes(authority_id: AuthorityId, registry: os.stat_result) -> bytes:
    marker = AuthorityMarker(
        authority_id=authority_id, schema_version=AUTHORITY_SCHEMA,
        registry_device=registry.st_dev, registry_inode=registry.st_ino,
        registry_mode=stat.S_IMODE(registry.st_mode), registry_owner=registry.st_uid,
        registry_links=registry.st_nlink, registry_digest=hashlib.sha256(b"").hexdigest(),
        root_inventory_digest=ROOT_INVENTORY_DIGEST, layout_digest=LAYOUT_DIGEST,
    )
    return _marker_bytes(marker)


def _parse_authority_marker(data: bytes) -> AuthorityMarker:
    try:
        value = AuthorityMarker.model_validate_json(data)
    except ValidationError as error:
        raise WeeklyOperationsCorruption("authority schema marker is malformed") from error
    authority_id = AuthorityId(value.authority_id)
    valid = (
        value.schema_version == AUTHORITY_SCHEMA
        and len(authority_id) == 64
        and not any(character not in "0123456789abcdef" for character in authority_id)
        and value.registry_mode == 0o600 and value.registry_owner == os.geteuid()
        and value.registry_links == 1 and value.registry_digest == hashlib.sha256(b"").hexdigest()
        and value.root_inventory_digest == ROOT_INVENTORY_DIGEST
        and value.layout_digest == LAYOUT_DIGEST and data == _marker_bytes(value)
    )
    if not valid:
        raise WeeklyOperationsCorruption("authority schema marker disagrees")
    return value


def canonical_authority_marker(data: bytes) -> bool:
    try:
        _ = _parse_authority_marker(data)
    except WeeklyOperationsCorruption:
        return False
    return True


def read_authority_marker(descriptor: int) -> tuple[AuthorityMarker, str, os.stat_result]:
    try:
        marker = os.open(MARKER_NAME, os.O_RDONLY | os.O_NOFOLLOW | os.O_CLOEXEC | os.O_NONBLOCK, dir_fd=descriptor)
    except OSError as error:
        raise WeeklyOperationsCorruption("authority schema marker is missing or unsafe") from error
    try:
        info = os.fstat(marker)
        named = os.stat(MARKER_NAME, dir_fd=descriptor, follow_symlinks=False)
        chunks: list[bytes] = []
        while chunk := os.read(marker, 4096):
            chunks.append(chunk)
        data = b"".join(chunks)
        safe = stat.S_ISREG(info.st_mode) and info.st_uid == os.geteuid() and info.st_nlink == 1 and stat.S_IMODE(info.st_mode) == 0o600
        if not safe or (info.st_dev, info.st_ino) != (named.st_dev, named.st_ino):
            raise WeeklyOperationsCorruption("authority schema marker identity drift")
    finally:
        os.close(marker)
    return _parse_authority_marker(data), hashlib.sha256(data).hexdigest(), info
