"""PAPER-23 honesty probe (M2 Wave-2 §1.5) — the pytest-plugin
silence warns loudly, and every deliberate silence stays silent."""

from __future__ import annotations

import sys
import warnings

import pytest

from mgf.common import _plugin_probe as probe


@pytest.fixture(autouse=True)
def _reset_latch(monkeypatch: pytest.MonkeyPatch):
    monkeypatch.setattr(probe, "_probed", False)
    yield


def _simulate_plugin_absent(monkeypatch: pytest.MonkeyPatch) -> None:
    """The PAPER-23 state: module never loaded, no entry point visible."""
    monkeypatch.delitem(sys.modules, "mgf.common.pytest_plugin", raising=False)
    monkeypatch.setattr(probe, "_entry_point_visible", lambda: False)


class TestWarnsOnTheSilence:
    def test_warns_when_plugin_absent_and_no_entry_point(
        self, monkeypatch: pytest.MonkeyPatch
    ) -> None:
        _simulate_plugin_absent(monkeypatch)
        # PYTEST_CURRENT_TEST is naturally set — we ARE inside a test.
        with pytest.warns(probe.MgfPytestPluginMissingWarning, match="PAPER-23"):
            probe.warn_if_plugin_silently_absent()

    def test_warning_names_the_conftest_fix_and_kill_switch(
        self, monkeypatch: pytest.MonkeyPatch
    ) -> None:
        _simulate_plugin_absent(monkeypatch)
        with pytest.warns(probe.MgfPytestPluginMissingWarning) as rec:
            probe.warn_if_plugin_silently_absent()
        msg = str(rec[0].message)
        assert 'pytest_plugins = ["mgf.common.pytest_plugin"]' in msg
        assert "MGF_COMMON_NO_PLUGIN_WARN" in msg

    def test_warns_once_per_process(self, monkeypatch: pytest.MonkeyPatch) -> None:
        _simulate_plugin_absent(monkeypatch)
        with pytest.warns(probe.MgfPytestPluginMissingWarning):
            probe.warn_if_plugin_silently_absent()
        with warnings.catch_warnings():
            warnings.simplefilter("error")
            probe.warn_if_plugin_silently_absent()  # latched — no second warning


class TestDeliberateSilences:
    def test_silent_when_plugin_loaded(self) -> None:
        # mgf-common's own suite runs with the plugin loaded (entry
        # point from the editable install) — the common healthy case.
        assert "mgf.common.pytest_plugin" in sys.modules
        with warnings.catch_warnings():
            warnings.simplefilter("error")
            probe.warn_if_plugin_silently_absent()

    def test_silent_when_entry_point_visible_but_disabled(
        self, monkeypatch: pytest.MonkeyPatch
    ) -> None:
        # `-p no:mgf_common`: module not imported, but the entry point
        # exists — an explicit opt-out, not the PAPER-23 silence.
        monkeypatch.delitem(sys.modules, "mgf.common.pytest_plugin", raising=False)
        monkeypatch.setattr(probe, "_entry_point_visible", lambda: True)
        with warnings.catch_warnings():
            warnings.simplefilter("error")
            probe.warn_if_plugin_silently_absent()

    def test_silent_outside_pytest_and_does_not_latch(
        self, monkeypatch: pytest.MonkeyPatch
    ) -> None:
        _simulate_plugin_absent(monkeypatch)
        monkeypatch.delenv("PYTEST_CURRENT_TEST", raising=False)
        with warnings.catch_warnings():
            warnings.simplefilter("error")
            probe.warn_if_plugin_silently_absent()
        assert probe._probed is False  # a later in-test call still probes

    def test_kill_switch_silences(self, monkeypatch: pytest.MonkeyPatch) -> None:
        _simulate_plugin_absent(monkeypatch)
        monkeypatch.setenv("MGF_COMMON_NO_PLUGIN_WARN", "1")
        with warnings.catch_warnings():
            warnings.simplefilter("error")
            probe.warn_if_plugin_silently_absent()


class TestEntryPointVisibility:
    def test_real_metadata_sees_our_entry_point(self) -> None:
        # The editable install writes dist-info entry points, so the
        # real probe must find pytest11 -> mgf.common.pytest_plugin.
        assert probe._entry_point_visible() is True
