"""Tests for core/model_profiles_validate.py.

Validates that the cross-config drift detector raises CrossConfigDriftError
on each of the three drift conditions, and passes on a clean fixture.

NOTE: the live config in recoil/config/ has known cross-config drift today;
the clean-pass test uses a stripped fixture, NOT the live config.
"""

from __future__ import annotations

import pytest

from recoil.core.model_profiles_validate import validate_cross_config
from recoil.core.exceptions import CrossConfigDriftError


def _clean_fixtures() -> tuple[dict, dict, dict, dict]:
    """Return a 4-tuple (model_profiles, provider_strategy,
    pipeline_config, model_roles) with no drift."""
    model_profiles = {
        "schema_version": 1,
        "_doc": "fixture",
        "seedream-v4.5": {
            "modality": "image",
        },
        "seeddance-2.0": {
            "modality": "video",
            "coverage_mode_preferences": {
                "character_pass": "r2v",
                "env_with_frame": "i2v",
                "env_without_frame": "r2v",
            },
        },
        "kling-v3": {
            "modality": "video",
            "coverage_mode_preferences": {
                "character_pass": "i2v",
                "env_with_frame": "i2v",
                "env_without_frame": "t2v",
            },
        },
    }
    provider_strategy = {
        "schema_version": 1,
        "seedream-v4.5": {"primary": "fal", "primary_tier": "default"},
        "seeddance-2.0": {"primary": "fal", "primary_tier": "default"},
        "kling-v3": {"primary": "kling", "primary_tier": "standard_720p"},
    }
    pipeline_config = {
        "schema_version": 1,
        "coverage_strategy": {
            "_comment": "test fixture",
            "model_routing": {
                "_comment": "ignored — _-prefixed keys",
                "env_any_tier": "seeddance-2.0",
                "character_default": "seeddance-2.0",
                "climax": "kling-v3",
            },
        },
    }
    model_roles = {
        "_doc": "fixture",
        "image": {"production": "seedream-v4.5"},
        "video": {"i2v": "kling-v3", "t2v_default": "kling-v3"},
    }
    return model_profiles, provider_strategy, pipeline_config, model_roles


def test_clean_fixtures_pass() -> None:
    """No drift across the four configs → returns None."""
    mp, ps, pc, mr = _clean_fixtures()
    # Should not raise
    assert validate_cross_config(
        model_profiles=mp,
        provider_strategy=ps,
        pipeline_config=pc,
        model_roles=mr,
    ) is None


def test_provider_strategy_orphan_raises() -> None:
    """A provider_strategy key not in model_profiles → raises."""
    mp, ps, pc, mr = _clean_fixtures()
    ps["bogus-model-v1"] = {"primary": "fal", "primary_tier": "default"}
    with pytest.raises(CrossConfigDriftError, match=r"provider_strategy.*bogus-model-v1"):
        validate_cross_config(
            model_profiles=mp,
            provider_strategy=ps,
            pipeline_config=pc,
            model_roles=mr,
        )


def test_routing_to_model_without_coverage_modes_raises() -> None:
    """A routing target whose model_profiles entry lacks
    coverage_mode_preferences → raises."""
    mp, ps, pc, mr = _clean_fixtures()
    # seedream-v4.5 has no coverage_mode_preferences (it's an image model)
    pc["coverage_strategy"]["model_routing"]["character_default"] = "seedream-v4.5"
    with pytest.raises(CrossConfigDriftError, match=r"coverage_mode_preferences"):
        validate_cross_config(
            model_profiles=mp,
            provider_strategy=ps,
            pipeline_config=pc,
            model_roles=mr,
        )


def test_routing_to_unknown_model_raises() -> None:
    """A routing target not in model_profiles → raises."""
    mp, ps, pc, mr = _clean_fixtures()
    pc["coverage_strategy"]["model_routing"]["env_any_tier"] = "ghost-model-v9"
    with pytest.raises(CrossConfigDriftError, match=r"ghost-model-v9"):
        validate_cross_config(
            model_profiles=mp,
            provider_strategy=ps,
            pipeline_config=pc,
            model_roles=mr,
        )


def test_model_roles_unknown_model_raises() -> None:
    """A role-leaf model id not in model_profiles → raises."""
    mp, ps, pc, mr = _clean_fixtures()
    mr["text"] = {"flash": "missing-model-x"}
    with pytest.raises(CrossConfigDriftError, match=r"missing-model-x"):
        validate_cross_config(
            model_profiles=mp,
            provider_strategy=ps,
            pipeline_config=pc,
            model_roles=mr,
        )
