"""Smoke tests for the ``mgf.common`` core public surface.

Build-broken signal (tier-0): if these fail, the wheel is broken or
the public surface moved — surface it in milliseconds, before any
heavier suite. Pure imports + cheap constructions; no fixtures, no
I/O, no subprocess, no bootstrap side-effects on process identity.

These complement :mod:`tests.smoke.test_process_smoke` (which covers
``mgf.common.process``) and exist so ``mtest --tier 0`` selects a
fast core sanity set rather than being dominated by the ~32 s
supervisor self-check.

Run in isolation::

    pytest -m smoke
"""

from __future__ import annotations

import pytest

pytestmark = pytest.mark.smoke


def test_package_imports() -> None:
    # The top-level package imports and exposes its public identity API.
    import mgf.common as m

    assert isinstance(m.__version__, str)
    for name in (
        "AppContext",
        "bootstrap",
        "bootstrap_for_test",
        "current_context",
        "app_name",
        "app_version",
        "add_help_note",
    ):
        assert name in m.__all__, f"{name} missing from mgf.common.__all__"
        assert hasattr(m, name), f"mgf.common.{name} not importable"


def test_bootstrap_helpers_importable() -> None:
    from mgf.common import bootstrap, bootstrap_for_test

    assert callable(bootstrap)
    assert callable(bootstrap_for_test)


def test_exception_bases_import() -> None:
    # The core error taxonomy is reachable and AppError is the root.
    from mgf.common.exceptions import (
        AppConfigError,
        AppError,
        ConfigError,
        OperationError,
    )

    assert issubclass(OperationError, AppError)
    assert issubclass(ConfigError, AppError)
    assert issubclass(AppConfigError, ConfigError)
    # AppError is constructible and is a plain Exception subclass.
    err = AppError("boom")
    assert isinstance(err, Exception)
    assert str(err) == "boom"


def test_redactor_constructs() -> None:
    from mgf.common.observability import DEFAULT_REDACTION_KEYS, Redactor

    r = Redactor.default()
    assert r is not None
    # Default policy includes the canonical secret-bearing key names.
    assert "password" in DEFAULT_REDACTION_KEYS
    assert "token" in DEFAULT_REDACTION_KEYS
    # The shortest happy path: a secret-named key is scrubbed in place.
    payload = {"password": "hunter2", "name": "ok"}
    r.redact(payload)
    assert payload["password"] != "hunter2"
    assert payload["name"] == "ok"


def test_base_app_settings_imports() -> None:
    from mgf.common.config import BaseAppSettings, settings_config

    assert callable(settings_config)
    # Constructing the base directly works (no fields required beyond
    # the default ``version``) and does not touch disk.
    s = BaseAppSettings()
    assert s.version == 1
