"""User-perspective tests for ``mgf.common.config``.

Surfaces exercised:
  - :class:`BaseAppSettings` (subclass-kwarg pattern; v0.3 Phase 2)
  - :func:`settings_config` helper
  - :func:`load_settings` / :func:`save_settings` (atomic round-trip)
  - :func:`platform_dir` / :func:`default_config_path`
  - Pydantic re-exports: ``BaseModel`` / ``Field`` / ``ConfigDict``
    (so consumers don't ``import pydantic`` directly)
"""

from __future__ import annotations

from typing import TYPE_CHECKING

from mgf.common.config import (
    BaseAppSettings,
    BaseModel,
    ConfigDict,
    Field,
    default_config_path,
    load_settings,
    platform_dir,
    save_settings,
    settings_config,
)

if TYPE_CHECKING:
    from pathlib import Path


class TestSubclassKwargs:
    """v0.3 Phase 2 canonical pattern — env_prefix as a subclass
    kwarg (no helper call needed)."""

    def test_subclass_kwarg_form(self) -> None:
        class MyAppSettings(BaseAppSettings, env_prefix="MYAPP_"):
            backend_uri: str = "qemu:///system"
            timeout_seconds: int = 30

        s = MyAppSettings()
        assert s.backend_uri == "qemu:///system"
        assert s.timeout_seconds == 30
        # The env_prefix flowed through to model_config:
        assert s.model_config["env_prefix"] == "MYAPP_"


class TestSettingsConfigHelper:
    def test_explicit_helper_form(self) -> None:
        class MyAppSettings(BaseAppSettings):
            model_config = settings_config(env_prefix="MYAPP_")
            field: str = "default"

        s = MyAppSettings()
        assert s.field == "default"
        assert s.model_config["env_prefix"] == "MYAPP_"


class TestPydanticReexports:
    """Consumers don't ``import pydantic`` for normal authoring
    (CB-04 closure in v0.3 Phase 2)."""

    def test_can_define_nested_basemodel_without_pydantic_import(self) -> None:
        class Sub(BaseModel):
            model_config = ConfigDict(extra="forbid")
            inner: str = "x"

        class MyApp(BaseAppSettings, env_prefix="X_"):
            sub: Sub = Field(default_factory=Sub)

        s = MyApp()
        assert s.sub.inner == "x"


class TestRoundTrip:
    def test_save_and_load(self, tmp_path: Path) -> None:
        class MyApp(BaseAppSettings, env_prefix="X_"):
            field: str = "default"

        s = MyApp(field="custom")
        path = tmp_path / "config.yaml"
        save_settings(s, path)
        assert path.exists()

        loaded = load_settings(MyApp, path=path)
        assert loaded.field == "custom"


class TestPlatformDirs:
    def test_platform_dir_returns_path(self) -> None:
        for kind in ("config", "state", "data"):
            p = platform_dir(kind)  # type: ignore[arg-type]
            # Just verify it's a Path-like thing — actual path value
            # depends on the host OS.
            assert hasattr(p, "exists")

    def test_default_config_path_with_explicit_app(self) -> None:
        # Passing ``app=`` skips the ``app_name()`` fallback, which
        # warns when no bootstrap is active. The user-perspective
        # path: pass your app name explicitly.
        p = default_config_path(app="myapp")
        assert hasattr(p, "exists")
        assert "myapp" in str(p)
