"""BOOTSTRAP-01 — ``.env`` files honour ``env_prefix``.

Pre-fix behaviour: a ``BaseAppSettings`` subclass with
``env_prefix="MGF_"`` and ``extra="forbid"`` would raise
``ValidationError`` if the project's ``.env`` carried unprefixed keys
(``SECRET_KEY``, ``DB_NAME``, etc.) — pydantic-settings 2.x's default
``DotEnvSettingsSource`` reads every key and tries to map them.

Post-fix: ``settings_config()`` defaults ``dotenv_filtering="match_prefix"``,
which makes the dotenv source only surface keys matching the
configured prefix. Unprefixed keys belong to other tools (Django,
SQLAlchemy, Celery, …) and are silently ignored.
"""

from __future__ import annotations

import textwrap
from typing import TYPE_CHECKING

from mgf.common.config import BaseAppSettings
from mgf.common.config._settings import settings_config

if TYPE_CHECKING:
    from pathlib import Path


def _write_env_file(tmp_path: Path, body: str) -> Path:
    env_path = tmp_path / ".env"
    env_path.write_text(textwrap.dedent(body).strip() + "\n")
    return env_path


class TestDotenvPrefixFilter:
    def test_unprefixed_keys_in_dotenv_dont_break_extra_forbid(
        self,
        tmp_path: Path,
    ) -> None:
        # Reproduces the BOOTSTRAP-01 scenario: a Django-style .env
        # with SECRET_KEY / DB_* / ALLOWED_HOSTS / CELERY_BROKER_URL
        # alongside MGF_-prefixed keys. The MGF subclass should pick
        # up MGF_FEATURE_FLAG and ignore the rest.
        env_file = _write_env_file(
            tmp_path,
            """
            SECRET_KEY=dev-test-secret-key-not-for-production
            ALLOWED_HOSTS=localhost,127.0.0.1
            DB_NAME=inthewords
            DB_USER=django_user
            DB_PASSWORD=hunter2
            REDIS_HOST=redis
            CELERY_BROKER_URL=redis://redis:6379/0
            MGF_FEATURE_FLAG=true
            """,
        )

        class _MgfStyle(BaseAppSettings):
            model_config = settings_config(
                env_prefix="MGF_",
                env_file=str(env_file),
            )
            feature_flag: bool = False

        settings = _MgfStyle()
        assert settings.feature_flag is True

    def test_prefix_match_strips_prefix_for_field_lookup(
        self,
        tmp_path: Path,
    ) -> None:
        # Verify MGF_-prefixed keys still bind to fields (the prefix
        # is stripped before matching). Regression check for
        # match_prefix mode mishandling the prefix-strip.
        env_file = _write_env_file(
            tmp_path,
            """
            UNRELATED_KEY=ignored
            ANOTHER_UNRELATED=also_ignored
            MGF_TOP=top-value
            MGF_OTHER=other-value
            """,
        )

        class _MgfStyle(BaseAppSettings):
            model_config = settings_config(
                env_prefix="MGF_",
                env_file=str(env_file),
            )
            top: str = "default-top"
            other: str = "default-other"

        settings = _MgfStyle()
        assert settings.top == "top-value"
        assert settings.other == "other-value"

    def test_no_prefix_consumer_unaffected(self, tmp_path: Path) -> None:
        # Consumers with env_prefix="" (no prefix) — match_prefix with
        # an empty prefix matches every key, preserving the "read
        # everything" behaviour. Single-tenant .env files keep working.
        env_file = _write_env_file(
            tmp_path,
            """
            FIELD_A=alpha
            """,
        )

        class _NoPrefix(BaseAppSettings):
            model_config = settings_config(
                env_prefix="",
                env_file=str(env_file),
                # Allow extras so unrelated keys don't raise — the
                # match_prefix change doesn't filter when prefix is
                # empty, which is correct semantics.
                extra="ignore",
            )
            field_a: str = "default"

        settings = _NoPrefix()
        assert settings.field_a == "alpha"
