"""Tests for complyform.core.auth.tier_config."""

from __future__ import annotations

import pytest

from complyform.core.auth.tier_config import (
    ALL_FRAMEWORKS,
    FREE_FRAMEWORKS,
    ME_FRAMEWORKS,
    TIER_CONFIG,
    VALID_TIERS,
    get_tier_config,
)


class TestTierConfig:
    def test_all_six_tiers_present(self) -> None:
        for tier in VALID_TIERS:
            assert tier in TIER_CONFIG

    def test_valid_tiers_tuple(self) -> None:
        assert VALID_TIERS == (
            "community",
            "pro",
            "team",
            "agency",
            "enterprise",
            "enterprise_unlimited",
        )

    def test_all_frameworks_has_53_entries(self) -> None:
        assert len(ALL_FRAMEWORKS) == 53

    def test_free_frameworks_has_4_entries(self) -> None:
        assert len(FREE_FRAMEWORKS) == 4
        assert frozenset({"soc2", "cis_gcp", "cis_azure", "cis_aws"}) == FREE_FRAMEWORKS

    def test_me_frameworks_has_17_entries(self) -> None:
        assert len(ME_FRAMEWORKS) == 17

    def test_free_frameworks_subset_of_all(self) -> None:
        assert FREE_FRAMEWORKS <= ALL_FRAMEWORKS

    def test_me_frameworks_subset_of_all(self) -> None:
        assert ME_FRAMEWORKS <= ALL_FRAMEWORKS

    def test_community_remediate_matches_free(self) -> None:
        cfg = get_tier_config("community")
        remediate = cfg["remediate_frameworks"]
        assert isinstance(remediate, list)
        assert frozenset(remediate) == FREE_FRAMEWORKS

    def test_get_tier_config_valid(self) -> None:
        cfg = get_tier_config("pro")
        assert "remediate_frameworks" in cfg
        assert "features" in cfg

    def test_get_tier_config_invalid_raises(self) -> None:
        with pytest.raises(KeyError):
            get_tier_config("invalid")

    def test_every_tier_has_required_keys(self) -> None:
        required = {
            "price_annual",
            "assess_frameworks",
            "remediate_frameworks",
            "scan_sources",
            "features",
            "project_limit",
            "batch_limit",
            "discover_limit",
        }
        for tier in VALID_TIERS:
            cfg = get_tier_config(tier)
            assert required <= set(cfg.keys()), f"{tier} missing keys"

    def test_assess_is_all_for_every_tier(self) -> None:
        for tier in VALID_TIERS:
            cfg = get_tier_config(tier)
            assert cfg["assess_frameworks"] == ["all"]

    @pytest.mark.parametrize(
        "tier",
        ["community", "pro", "team", "agency", "enterprise", "enterprise_unlimited"],
    )
    def test_no_phantom_feature_keys(self, tier: str) -> None:
        known_features = {
            "html_report",
            "github_action",
            "checkov_custom",
            "multi_state_remediate",
            "batch_scan_assess",
            "pr_remediation",
            "ai_explain",
            "hosted_dashboard",
            "drift_alerts",
            "drift_event_driven",
            "opa_rego",
            "validation_api",
            "evidence_export_native",
            "evidence_export_grc",
            "evidence_export_batch",
            "iam_analysis",
            "cross_validation",
            "cost_impact",
            "sso_saml",
            "enforce_sso",
            "scim_provisioning",
            "team_members",
            "audit_log",
            "webhooks",
            "data_residency",
            "shared_scan_links",
            "signed_attestations",
            "branded_pdf",
            "multi_project_dashboard",
            "batch_scan",
            "batch_remediate",
            "air_gap",
            "ip_allowlist",
            "annual_fw_revision_email",
            "custom_sub_framework",
            "dedicated_slack_support",
        }
        cfg = get_tier_config(tier)
        features = cfg["features"]
        assert isinstance(features, list)
        for f in features:
            assert f in known_features, f"Unknown feature '{f}' in tier '{tier}'"

    def test_tier_remediate_frameworks_cumulative(self) -> None:
        """Higher tiers include all frameworks from lower tiers."""
        tiers_ordered = ["community", "pro", "team", "agency"]
        for i in range(1, len(tiers_ordered)):
            lower = get_tier_config(tiers_ordered[i - 1])
            higher = get_tier_config(tiers_ordered[i])
            lower_fws = set(lower["remediate_frameworks"])  # type: ignore[arg-type]
            higher_fws = set(higher["remediate_frameworks"])  # type: ignore[arg-type]
            assert lower_fws <= higher_fws, (
                f"{tiers_ordered[i]} missing frameworks from {tiers_ordered[i - 1]}"
            )
