"""Event-driven registry swap race for default reminder bootstrap."""

from __future__ import annotations

import os
import sys
from pathlib import Path

import pytest

from gateway.platforms.nutrition_weekly_reminder_bootstrap import (
    WeeklyReminderStartupAuthorityIncident,
)
from gateway.platforms.telegram import TelegramAdapter
from tests.gateway._nutrition_weekly_reminder_support import (
    FakeTelegramHost,
    reminder_owner_fixture,
)
from tests.gateway.test_nutrition_weekly_reminder_bootstrap_boundary_r7 import (
    alternate_registry,
    platform_config,
)


def _fds() -> frozenset[int]:
    return frozenset(
        int(entry.name) for entry in Path("/proc/self/fd").iterdir()
    )


def _profile_bytes(root: Path) -> dict[str, bytes]:
    return {
        str(path.relative_to(root)): path.read_bytes()
        for path in root.rglob("*")
        if path.is_file()
    }


@pytest.mark.parametrize("attempt", (1, 2))
def test_registry_swap_during_bootstrap_fails_after_retained_fd_recheck(
    tmp_path: Path, attempt: int,
) -> None:
    assert attempt in (1, 2)
    fixture = reminder_owner_fixture(tmp_path)
    registry = fixture.registry_path
    payload = registry.read_bytes()
    config = platform_config(tmp_path, fixture.extra)
    active = [True]
    baseline_fds = _fds()
    baseline_bytes = _profile_bytes(tmp_path)

    def swap_after_pin(event: str, arguments: tuple[str]) -> None:
        if (
            active[0]
            and event == "nutricoach.weekly_reminder.customers_constructed"
            and arguments == ("registry.json",)
        ):
            active[0] = False
            alternate = alternate_registry(registry, payload)
            os.replace(alternate, registry)

    sys.addaudithook(swap_after_pin)
    provider = FakeTelegramHost()
    try:
        with pytest.raises(WeeklyReminderStartupAuthorityIncident):
            _ = TelegramAdapter(config)
        assert not active[0]
        assert provider.calls == 0
        assert _fds() == baseline_fds
        assert _profile_bytes(tmp_path) == baseline_bytes
    finally:
        active[0] = False
        fixture.owner.close()
