"""Тесты для app/core/shutdown.py — кооперативный SIGTERM-флаг (#1182 Phase 2)."""

from __future__ import annotations

import asyncio

import pytest

from app.core import shutdown as sd


@pytest.fixture(autouse=True)
def _reset() -> None:
    """Event — module-global: сбрасываем до и после каждого теста для изоляции."""
    sd.reset_shutdown()
    yield
    sd.reset_shutdown()


def test_default_not_requested() -> None:
    """По умолчанию shutdown не запрошен."""
    assert sd.shutdown_requested() is False


def test_request_sets_flag() -> None:
    """request_shutdown() выставляет флаг."""
    sd.request_shutdown()
    assert sd.shutdown_requested() is True


def test_request_is_idempotent() -> None:
    """Повторный request_shutdown() безвреден — флаг остаётся True."""
    sd.request_shutdown()
    sd.request_shutdown()
    assert sd.shutdown_requested() is True


def test_reset_clears_flag() -> None:
    """reset_shutdown() (test-only) снимает флаг."""
    sd.request_shutdown()
    assert sd.shutdown_requested() is True
    sd.reset_shutdown()
    assert sd.shutdown_requested() is False


@pytest.mark.asyncio
async def test_wait_for_shutdown_blocks_until_requested() -> None:
    """wait_for_shutdown() висит, пока не вызван request_shutdown()."""
    waiter = asyncio.create_task(sd.wait_for_shutdown())
    await asyncio.sleep(0.02)
    assert not waiter.done(), "не должен завершиться до request_shutdown()"

    sd.request_shutdown()
    await asyncio.wait_for(waiter, timeout=1.0)
    assert waiter.done()


@pytest.mark.asyncio
async def test_wait_for_shutdown_returns_immediately_if_already_set() -> None:
    """Если флаг уже выставлен, wait_for_shutdown() возвращается сразу."""
    sd.request_shutdown()
    await asyncio.wait_for(sd.wait_for_shutdown(), timeout=1.0)
