"""Tests for OpenCode Zen model registry functionality."""

import json
import os
import tempfile
from unittest.mock import patch

from providers.registries.zen import ZenModelRegistry
from providers.shared import ProviderType


class TestZenModelRegistry:
    """Test cases for Zen model registry."""

    def test_registry_initialization(self):
        """Test registry initializes with default config."""
        registry = ZenModelRegistry()

        # Should load models from default location
        assert len(registry.list_models()) > 0
        assert len(registry.list_aliases()) > 0

        # Should include our configured models
        assert "claude-sonnet-4-5" in registry.list_models()
        assert "gpt-5.1-codex" in registry.list_models()

    def test_custom_config_path(self):
        """Test registry with custom config path."""
        # Create temporary config
        config_data = {
            "models": [
                {
                    "model_name": "test/zen-model-1",
                    "aliases": ["zen-test1", "zt1"],
                    "context_window": 4096,
                    "max_output_tokens": 2048,
                    "intelligence_score": 15,
                }
            ]
        }

        with tempfile.NamedTemporaryFile(mode="w", suffix=".json", delete=False) as f:
            json.dump(config_data, f)
            temp_path = f.name

        try:
            registry = ZenModelRegistry(config_path=temp_path)
            assert len(registry.list_models()) == 1
            assert "test/zen-model-1" in registry.list_models()
            assert "zen-test1" in registry.list_aliases()
            assert "zt1" in registry.list_aliases()
        finally:
            os.unlink(temp_path)

    def test_get_capabilities(self):
        """Test capability retrieval."""
        registry = ZenModelRegistry()

        # Test getting capabilities for a known model
        caps = registry.get_capabilities("claude-sonnet-4-5")
        assert caps is not None
        assert caps.provider == ProviderType.ZEN
        assert caps.model_name == "claude-sonnet-4-5"
        assert caps.friendly_name == "OpenCode Zen (claude-sonnet-4-5)"
        assert caps.context_window == 200000
        assert caps.intelligence_score == 17

        # Test getting capabilities for unknown model
        caps = registry.get_capabilities("unknown-model")
        assert caps is None

    def test_resolve_model(self):
        """Test model resolution with aliases."""
        registry = ZenModelRegistry()

        # Test resolving a direct model name
        config = registry.resolve("claude-sonnet-4-5")
        assert config is not None
        assert config.model_name == "claude-sonnet-4-5"

        # Test resolving an alias
        config = registry.resolve("zen-sonnet")
        assert config is not None
        assert config.model_name == "claude-sonnet-4-5"

        # Test resolving unknown model
        config = registry.resolve("unknown-model")
        assert config is None

    def test_list_aliases(self):
        """Test alias listing."""
        registry = ZenModelRegistry()

        aliases = registry.list_aliases()
        assert isinstance(aliases, list)
        assert len(aliases) > 0

        # Should include our configured aliases
        assert "zen-sonnet" in aliases
        assert "zen-codex" in aliases
        assert "zen-gemini" in aliases

    def test_environment_config_path(self):
        """Test registry respects environment variable for config path."""
        config_data = {
            "models": [
                {
                    "model_name": "env/test-model",
                    "aliases": ["env-test"],
                    "context_window": 8192,
                    "max_output_tokens": 4096,
                    "intelligence_score": 10,
                }
            ]
        }

        with tempfile.NamedTemporaryFile(mode="w", suffix=".json", delete=False) as f:
            json.dump(config_data, f)
            temp_path = f.name

        try:
            with patch.dict(os.environ, {"ZEN_MODELS_CONFIG_PATH": temp_path}):
                registry = ZenModelRegistry()
                assert "env/test-model" in registry.list_models()
                assert "env-test" in registry.list_aliases()
        finally:
            os.unlink(temp_path)

    def test_malformed_config(self):
        """Test registry handles malformed config gracefully."""
        malformed_config = {
            "models": [
                {
                    "model_name": "test/bad-model",
                    # Missing required fields
                }
            ]
        }

        with tempfile.NamedTemporaryFile(mode="w", suffix=".json", delete=False) as f:
            json.dump(malformed_config, f)
            temp_path = f.name

        try:
            registry = ZenModelRegistry(config_path=temp_path)
            # Should still initialize but model may not load properly
            # This tests error handling in config loading
            registry.list_models()  # Test that this doesn't crash
            # May or may not include the malformed model depending on validation
        finally:
            os.unlink(temp_path)

    def test_empty_config(self):
        """Test registry with empty config."""
        empty_config = {"models": []}

        with tempfile.NamedTemporaryFile(mode="w", suffix=".json", delete=False) as f:
            json.dump(empty_config, f)
            temp_path = f.name

        try:
            registry = ZenModelRegistry(config_path=temp_path)
            assert len(registry.list_models()) == 0
            assert len(registry.list_aliases()) == 0
        finally:
            os.unlink(temp_path)
