"""Smoke tests for ``example_app`` — the v0.4 Phase G3 second consumer.

These tests validate that the v0.4 ``mgf-common`` public surface
is usable end-to-end from a real packaged consumer:

  - ``bootstrap_for_test()`` works (Phase F).
  - ``AppSettings`` composition (Phase F docs canonical pattern).
  - ``register_cli_subcommand`` + ``build_cli`` end-to-end (Phase E).
  - ``MgfSettings.testing()`` factory (Phase C).

They run separately from ``mgf-common``'s own test suite —
``cd example_app && pytest`` — so the consumer-vs-library
separation is preserved.
"""

from __future__ import annotations

from typing import TYPE_CHECKING

import pytest

from mgf.common import bootstrap_for_test
from mgf.common.settings import LoggingSettings, MgfSettings

from example_app.cli import main
from example_app.settings import AppSettings

if TYPE_CHECKING:
    pass


@pytest.fixture(autouse=True)
def _disable_pyproject(monkeypatch: pytest.MonkeyPatch) -> None:
    """Disable mgf-common's pyproject.toml source for hermetic tests."""
    monkeypatch.setenv("MGF_DISABLE_PYPROJECT", "1")


class TestSettingsComposition:
    """Phase F canonical pattern — consumer Settings carries
    ``mgf: MgfSettings`` as a sub-field."""

    def test_app_settings_has_mgf_subfield(self) -> None:
        s = AppSettings()
        assert isinstance(s.mgf, MgfSettings)

    def test_app_settings_default_greeting(self) -> None:
        s = AppSettings()
        assert s.greeting == "Hello"

    def test_app_settings_env_override(
        self, monkeypatch: pytest.MonkeyPatch,
    ) -> None:
        monkeypatch.setenv("EXAMPLE_APP_GREETING", "Howdy")
        s = AppSettings()
        assert s.greeting == "Howdy"

    def test_mgf_subfield_env_override(
        self, monkeypatch: pytest.MonkeyPatch,
    ) -> None:
        """Nested env: ``EXAMPLE_APP_MGF__LOGGING__LEVEL=DEBUG``
        flows into the mgf sub-field."""
        monkeypatch.setenv("EXAMPLE_APP_MGF__LOGGING__LEVEL", "DEBUG")
        s = AppSettings()
        assert s.mgf.logging.level == "DEBUG"


class TestBootstrapForTest:
    """Phase F bootstrap_for_test integration."""

    def test_bootstrap_for_test_returns_context(self) -> None:
        with bootstrap_for_test() as ctx:
            assert ctx.app_name == "test-app"
            assert ctx.settings.preset == "explicit"

    def test_bootstrap_for_test_with_custom_settings(self) -> None:
        custom = MgfSettings.testing(logging=LoggingSettings(level="DEBUG"))
        with bootstrap_for_test(settings=custom) as ctx:
            assert ctx.settings.logging.level == "DEBUG"


class TestCliEndToEnd:
    """Phase E composable-CLI integration: the example-app's
    ``greet`` subcommand goes through the shared registry."""

    def test_greet_subcommand_runs(
        self, capsys: pytest.CaptureFixture[str],
    ) -> None:
        rc = main(["greet", "--name", "Alice"])
        assert rc == 0
        out = capsys.readouterr().out
        assert "Hello, Alice!" in out

    def test_greet_subcommand_default_name(
        self, capsys: pytest.CaptureFixture[str],
    ) -> None:
        rc = main(["greet"])
        assert rc == 0
        out = capsys.readouterr().out
        assert "Hello, world!" in out

    def test_greet_with_custom_greeting(
        self,
        capsys: pytest.CaptureFixture[str],
        monkeypatch: pytest.MonkeyPatch,
    ) -> None:
        """Domain settings drive behaviour — env override flows through."""
        monkeypatch.setenv("EXAMPLE_APP_GREETING", "Salut")
        rc = main(["greet", "--name", "Bob"])
        assert rc == 0
        out = capsys.readouterr().out
        assert "Salut, Bob!" in out

    def test_builtin_diagnostics_visible(
        self, capsys: pytest.CaptureFixture[str],
    ) -> None:
        """``include_builtins=True`` + the mgf-fed[cli] provider —
        the shared diagnostic subcommands are reachable from the
        consumer's CLI (post-extraction: registration lives in
        mgf-fed; ``doctor`` became ``app-doctor``)."""
        rc = main(["explain"])
        # explain prints the resolved settings; 0 in a healthy env,
        # 2 if a check fails — the point is the subcommand was
        # dispatched and didn't crash.
        assert rc in (0, 2)
