"""ORCH-079 (ORCH-52f): structural anti-drift for README "Известные ограничения".

Layer 5 (final) of epic ORCH-52: the root README overview showcase must not lie
about the project state. These are pure-text structural checks (NO `src/` import,
NO agent runs) guarding two invariants (TRZ §FR-1/FR-2, AC-1/AC-2):

  * the OPEN limitations list is numbered strictly 1, 2, 3, … without repeats
    (the historical bug was `1,2,3,4,3,4`);
  * resolved/obsolete items (single-task worktree, in-process daemon, "Gitea CI
    not configured", "no retry") are NOT listed as OPEN limitations — if mentioned
    at all, only under the "Закрыто (история)" trail.

Covers test-plan TC-05.
"""
import os
import re

_REPO_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
_README = os.path.join(_REPO_ROOT, "README.md")

# Heading of the limitations section and the closed-history subsection that ends
# the OPEN portion.
_SECTION_HEAD = "## Известные ограничения"
_CLOSED_HEAD = "Закрыто (история)"

# Phrases that mark a RESOLVED/obsolete item. They must not appear in the OPEN
# portion of the section (only allowed under "Закрыто (история)").
_RESOLVED_MARKERS = (
    "Single-task",
    "shared `/repos`",
    "daemon-потоки",
    "не настроен",  # "Gitea CI не настроен"
    "No retry",
)


def _read_readme() -> str:
    with open(_README, encoding="utf-8") as f:
        return f.read()


def _limitations_section() -> str:
    """Text of the '## Известные ограничения' section up to the next '## ' heading."""
    text = _read_readme()
    idx = text.find(_SECTION_HEAD)
    assert idx != -1, "README.md has no '## Известные ограничения' section"
    rest = text[idx + len(_SECTION_HEAD):]
    # Stop at the next top-level (##) heading, if any.
    nxt = re.search(r"\n## ", rest)
    return rest[: nxt.start()] if nxt else rest


def _open_portion(section: str) -> str:
    """The OPEN-limitations portion: everything before the 'Закрыто (история)' trail."""
    cut = section.find(_CLOSED_HEAD)
    return section[:cut] if cut != -1 else section


def test_open_limitations_numbered_sequentially():
    """AC-1: the OPEN limitations list is numbered 1, 2, 3, … with no repeats/gaps."""
    open_part = _open_portion(_limitations_section())
    # Leading numbered list items: lines like "1. **...".
    numbers = [int(m) for m in re.findall(r"^(\d+)\.\s", open_part, flags=re.MULTILINE)]
    assert numbers, "no numbered OPEN limitations found in README section"
    assert numbers == list(range(1, len(numbers) + 1)), (
        f"OPEN limitations numbering is not strictly sequential: {numbers}"
    )


def test_resolved_items_not_listed_as_open():
    """AC-2: resolved/obsolete items are not present as OPEN limitations."""
    open_part = _open_portion(_limitations_section())
    leaked = [m for m in _RESOLVED_MARKERS if m in open_part]
    assert not leaked, (
        f"resolved items leaked into OPEN limitations (must be under 'Закрыто'): {leaked}"
    )


def test_closed_history_trail_present_with_orch_refs():
    """AC-2: the 'Закрыто (история)' trail exists and carries ORCH references."""
    section = _limitations_section()
    assert _CLOSED_HEAD in section, (
        "README limitations section lacks the 'Закрыто (история)' trail"
    )
    closed = section[section.find(_CLOSED_HEAD):]
    assert re.search(r"ORCH-\d+", closed), (
        "the 'Закрыто (история)' trail has no ORCH-NNN references"
    )
