"""Unit tests for :mod:`attractor.execution.elision` (SPEC §6.8)."""

from __future__ import annotations

import re

from attractor.execution.elision import ELISION_CAP, ELISION_HEAD, ELISION_TAIL, elide


# [unit->REQ-EXEC-TOOL-CAPTURE]
def test_short_output_returned_verbatim() -> None:
    """Buffers at or below the cap pass through unchanged."""
    payload = b"hello world\n"
    assert elide(payload) == "hello world\n"


# [unit->REQ-EXEC-TOOL-CAPTURE]
def test_empty_buffer() -> None:
    """Empty input is the empty string, not an elision marker."""
    assert elide(b"") == ""


# [unit->REQ-EXEC-TOOL-CAPTURE]
def test_exactly_at_cap_not_elided() -> None:
    """The cap is inclusive — exactly 512 KiB passes through whole."""
    payload = b"a" * ELISION_CAP
    out = elide(payload)
    assert "[...elided" not in out
    assert len(out) == ELISION_CAP


# [unit->REQ-EXEC-TOOL-CAPTURE]
def test_one_byte_over_cap_triggers_elision() -> None:
    """One byte over the cap is enough to drop a single byte from the
    middle and insert the marker."""
    payload = b"a" * (ELISION_CAP + 1)
    out = elide(payload)
    assert "[...elided 1 bytes...]" in out


# [unit->REQ-EXEC-TOOL-CAPTURE]
def test_elision_preserves_head_and_tail_segments() -> None:
    """When elision triggers the marker sits between the head/tail
    bytes; head is the first 256 KiB, tail the last 256 KiB."""
    head = b"H" * ELISION_HEAD
    middle = b"M" * (10 * 1024)
    tail = b"T" * ELISION_TAIL
    payload = head + middle + tail
    out = elide(payload)

    match = re.search(r"\[\.\.\.elided (\d+) bytes\.\.\.\]", out)
    assert match is not None, "elision marker missing"
    assert int(match.group(1)) == len(middle)

    marker_start = match.start()
    marker_end = match.end()
    assert out[:marker_start] == "H" * ELISION_HEAD
    assert out[marker_end:] == "T" * ELISION_TAIL


# [unit->REQ-EXEC-TOOL-CAPTURE]
def test_elision_lossy_decode_at_boundary() -> None:
    """A multibyte UTF-8 rune split by the elision boundary degrades
    to U+FFFD rather than raising :class:`UnicodeDecodeError`."""
    # First two bytes of "é" (0xC3 0xA9) sit at the end of the head
    # region; the third payload byte is junk so the segment ends
    # mid-rune. Decoding must not raise.
    head = b"x" * (ELISION_HEAD - 1) + b"\xc3"
    middle = b"M" * (10 * 1024)
    tail = b"\xa9" + b"y" * (ELISION_TAIL - 1)
    out = elide(head + middle + tail)
    # Replacement char appears at the broken boundaries.
    assert "�" in out


# [unit->REQ-EXEC-TOOL-CAPTURE]
def test_marker_byte_count_matches_dropped_middle() -> None:
    """``N`` in ``[...elided N bytes...]`` equals ``total - 2 * 256 KiB``."""
    extra = 7
    payload = b"a" * (ELISION_CAP + extra)
    out = elide(payload)
    match = re.search(r"\[\.\.\.elided (\d+) bytes\.\.\.\]", out)
    assert match is not None
    assert int(match.group(1)) == extra
