"""Tests for the deprecation + unconfigured warnings.

Covers:
- ``current_context()`` emits ``UnconfiguredWarning`` once when called
  before any bootstrap.
- The warning is one-shot — repeated calls don't spam.
- The ``_default_log_path`` / ``_crash_dir`` private aliases that
  predate PAPER-07 still emit ``MgfDeprecationWarning`` and delegate
  to the public helpers.

NOTE: the ``configure()`` deprecation tests that used to live here
were removed when ``configure()`` itself was removed in v0.33.0 per
its AP-12 cycle. Identity is now set via ``mgf.common.bootstrap()``
or, in tests, ``mgf.common.bootstrap_for_test()``.
"""

from __future__ import annotations

import warnings

import pytest

import mgf.common
from mgf.common._warnings import MgfDeprecationWarning


@pytest.fixture(autouse=True)
def _reset_phase_d_state(monkeypatch: pytest.MonkeyPatch) -> None:
    """Reset every relevant module global so each test sees fresh state.

    Also clear the contextvar to ensure no stray AppContext from a
    prior test leaks into ``current_context()`` calls here.
    """
    from mgf.common import _identity, _lifecycle

    # One-shot warning guards.
    monkeypatch.setattr(_identity, "_UNCONFIGURED_WARNED", False)
    monkeypatch.setattr(_lifecycle, "_CURRENT_CONTEXT_UNCONFIGURED_WARNED", False)

    # Identity globals — reset to defaults.
    monkeypatch.setattr(_identity, "_CONFIGURED", False)
    monkeypatch.setattr(_identity, "_APP_NAME", "app")
    monkeypatch.setattr(_identity, "_APP_VERSION", "unknown")

    # Process-wide context global.
    monkeypatch.setattr(_lifecycle, "_GLOBAL_CONTEXT", None)

    # Per-task contextvar.
    token = _lifecycle._CONTEXT_VAR.set(None)
    yield
    _lifecycle._CONTEXT_VAR.reset(token)


# ---------------------------------------------------------------------------
# current_context() pre-bootstrap warning
# ---------------------------------------------------------------------------


class TestCurrentContextPreBootstrap:
    """``_reset_phase_d_state`` autouse fixture above already cleans
    ``_GLOBAL_CONTEXT`` + the contextvar between tests."""

    def test_pre_bootstrap_emits_unconfigured_warning(self) -> None:
        with warnings.catch_warnings(record=True) as caught:
            warnings.simplefilter("always")
            result = mgf.common.current_context()

        assert result is None
        unconfigured = [w for w in caught if issubclass(w.category, mgf.common.UnconfiguredWarning)]
        assert len(unconfigured) == 1
        msg = str(unconfigured[0].message)
        assert "current_context() called before bootstrap()" in msg
        assert "bootstrap_for_test" in msg

    def test_pre_bootstrap_warning_is_one_shot(self) -> None:
        with warnings.catch_warnings(record=True) as caught:
            warnings.simplefilter("always")
            mgf.common.current_context()
            mgf.common.current_context()
            mgf.common.current_context()

        unconfigured = [w for w in caught if issubclass(w.category, mgf.common.UnconfiguredWarning)]
        # First call warns; subsequent calls are silent.
        assert len(unconfigured) == 1

    def test_post_bootstrap_no_warning(self) -> None:
        from mgf.common._test_helpers import bootstrap_for_test

        with bootstrap_for_test():
            with warnings.catch_warnings(record=True) as caught:
                warnings.simplefilter("always")
                ctx = mgf.common.current_context()
            # When bootstrap is active, current_context returns the
            # context and does NOT emit the warning.
            assert ctx is not None
            unconfigured = [
                w for w in caught if issubclass(w.category, mgf.common.UnconfiguredWarning)
            ]
            assert unconfigured == []


# ---------------------------------------------------------------------------
# v0.13 path-helper deprecations (closes FEEDBACK PAPER-07)
# ---------------------------------------------------------------------------


class TestPathHelperDeprecations:
    """``_default_log_path`` and ``_crash_dir`` are deprecated
    aliases for the public ``default_log_path`` /
    ``default_crash_dir`` helpers in ``mgf.common.observability``.
    Calling the underscored names emits ``MgfDeprecationWarning``
    and delegates to the public helper."""

    def test_default_log_path_alias_warns_and_delegates(self) -> None:
        from mgf.common.observability import default_log_path
        from mgf.common.observability.logging_setup import _default_log_path

        with warnings.catch_warnings(record=True) as caught:
            warnings.simplefilter("always")
            result = _default_log_path()

        deprecation_warnings = [w for w in caught if issubclass(w.category, MgfDeprecationWarning)]
        assert len(deprecation_warnings) == 1
        msg = str(deprecation_warnings[0].message)
        assert "_default_log_path" in msg
        assert "default_log_path" in msg
        # Delegation: the underscored alias returns the same value
        # the public helper would have produced.
        assert result == default_log_path()

    def test_crash_dir_alias_warns_and_delegates(self) -> None:
        from mgf.common.observability import default_crash_dir
        from mgf.common.observability.crash_reporter import _crash_dir

        with warnings.catch_warnings(record=True) as caught:
            warnings.simplefilter("always")
            result = _crash_dir()

        deprecation_warnings = [w for w in caught if issubclass(w.category, MgfDeprecationWarning)]
        assert len(deprecation_warnings) == 1
        msg = str(deprecation_warnings[0].message)
        assert "_crash_dir" in msg
        assert "default_crash_dir" in msg
        assert result == default_crash_dir()
