"""C13 FDR writer error types (AZ-291 / AZ-292 / AZ-293 / AZ-294 / AZ-295)."""

from __future__ import annotations

__all__ = [
    "FdrAlreadyClosedError",
    "FdrCloseWithoutOpenError",
    "FdrConcurrentWriterError",
    "FdrOpenError",
    "FdrWriterError",
    "RawFrameWriteForbiddenError",
    "TileSnapshotInvalidIdError",
    "TileSnapshotTooLargeError",
]


class TileSnapshotTooLargeError(ValueError):
    """Raised by `MidFlightTileSnapshotSink.write_snapshot` (AZ-294) when the
    input JPEG exceeds the configured ``jpeg_max_bytes`` ceiling.

    The sink does not trust producers to self-cap their JPEG size; this
    bound short-circuits adversarial / runaway producer behaviour before
    any sidecar file is written.
    """


class TileSnapshotInvalidIdError(ValueError):
    """Raised by `MidFlightTileSnapshotSink.write_snapshot` (AZ-294) when the
    input ``tile_id`` does not match the documented identifier regex.

    The regex rejects path-traversal sequences (e.g. ``../../etc/passwd``)
    and any character outside ``[a-zA-Z0-9_-]``; size is bounded to 128
    chars.
    """


class RawFrameWriteForbiddenError(RuntimeError):
    """Raised by `RecordKindPolicy.enforce_or_raise` (AZ-295) when a
    producer attempts to enqueue an `FdrRecord` whose ``kind`` is in
    the configured forbidden set (defaults to raw-frame variants).

    AC-8.5 / RESTRICT-UAV-4: raw nav/AI-cam frames are NEVER allowed on
    durable storage. The exception is raised SYNCHRONOUSLY at the
    producer's call site so the offending caller sees the security
    error immediately.
    """


class FdrWriterError(RuntimeError):
    """Base class for every C13 writer-side runtime error."""


class FdrConcurrentWriterError(FdrWriterError):
    """Raised when a second writer attempts to acquire the flight-root lock.

    The flight-root filelock is held for the entire flight (AZ-291 AC-4);
    a second writer construction against the same root is a composition-
    root bug.
    """


class FdrOpenError(FdrWriterError):
    """Raised when ``open_flight`` cannot land the ``flight_header`` record
    on disk (AZ-292 AC-4, AC-5) or when the writer cannot open segment 0.

    Translates to a takeoff abort in the composition root (AZ-296 wires
    that path); this task only raises the exception.
    """


class FdrCloseWithoutOpenError(FdrWriterError):
    """Raised by ``close_flight`` when ``open_flight`` was never called."""


class FdrAlreadyClosedError(FdrWriterError):
    """Raised by ``close_flight`` if called twice (AZ-292 idempotency)."""
