"""Feature flag configuration tests.

Verifies FeatureFlags class defaults and environment variable parsing.
"""

import pytest

from noteflow.config.settings import FeatureFlags, get_feature_flags


@pytest.fixture
def clear_feature_flags_cache() -> None:
    """Clear cached feature flags before each test."""
    get_feature_flags.cache_clear()


@pytest.mark.usefixtures("clear_feature_flags_cache")
class TestFeatureFlagDefaults:
    """Verify default values for feature flags.

    Note: These tests use monkeypatch to clear environment variables
    that would otherwise override the code defaults.
    """

    @pytest.mark.parametrize(
        ("attr", "expected"),
        [
            pytest.param("templates_enabled", True, id="templates-enabled"),
            pytest.param("pdf_export_enabled", True, id="pdf-export-enabled"),
            pytest.param("ner_enabled", False, id="ner-disabled"),
            pytest.param("calendar_enabled", False, id="calendar-disabled"),
            pytest.param("webhooks_enabled", True, id="webhooks-enabled"),
        ],
    )
    def test_default_values(self, attr: str, expected: bool) -> None:
        """Feature flags have correct default values in code (ignores .env)."""
        # Use model_construct to bypass env file reading and test pure code defaults
        flags = FeatureFlags.model_construct()
        actual = getattr(flags, attr)
        assert actual is expected, f"{attr} should default to {expected}"


@pytest.mark.usefixtures("clear_feature_flags_cache")
class TestFeatureFlagEnvironment:
    """Verify environment variable parsing."""

    @pytest.mark.parametrize(
        ("env_var", "attr", "value", "expected"),
        [
            pytest.param(
                "NOTEFLOW_FEATURE_NER_ENABLED",
                "ner_enabled",
                "true",
                True,
                id="ner-enabled-true",
            ),
            pytest.param(
                "NOTEFLOW_FEATURE_NER_ENABLED",
                "ner_enabled",
                "false",
                False,
                id="ner-enabled-false",
            ),
            pytest.param(
                "NOTEFLOW_FEATURE_CALENDAR_ENABLED",
                "calendar_enabled",
                "true",
                True,
                id="calendar-enabled-true",
            ),
            pytest.param(
                "NOTEFLOW_FEATURE_WEBHOOKS_ENABLED",
                "webhooks_enabled",
                "false",
                False,
                id="webhooks-disabled",
            ),
            pytest.param(
                "NOTEFLOW_FEATURE_TEMPLATES_ENABLED",
                "templates_enabled",
                "false",
                False,
                id="templates-disabled",
            ),
            pytest.param(
                "NOTEFLOW_FEATURE_PDF_EXPORT_ENABLED",
                "pdf_export_enabled",
                "false",
                False,
                id="pdf-export-disabled",
            ),
        ],
    )
    def test_env_var_parsing(
        self,
        monkeypatch: pytest.MonkeyPatch,
        env_var: str,
        attr: str,
        value: str,
        expected: bool,
    ) -> None:
        """Feature flags parse from environment variables."""
        monkeypatch.setenv(env_var, value)
        flags = get_feature_flags()
        actual = getattr(flags, attr)
        assert actual == expected, f"{attr} should be {expected} when {env_var}={value}"


@pytest.mark.usefixtures("clear_feature_flags_cache")
class TestFeatureFlagCaching:
    """Verify feature flags are cached."""

    def test_get_feature_flags_cached(self) -> None:
        """get_feature_flags returns same instance."""
        flags1 = get_feature_flags()
        flags2 = get_feature_flags()
        assert flags1 is flags2, "Should return cached instance"

    def test_cache_clear_returns_new_instance(self) -> None:
        """After cache_clear, a new instance is returned."""
        flags1 = get_feature_flags()
        get_feature_flags.cache_clear()
        flags2 = get_feature_flags()
        assert flags1 is not flags2, "Should return new instance after cache clear"
        assert flags1.ner_enabled == flags2.ner_enabled, "Values should match"
