"""Unit tests for resolution strategies."""

import pytest
from markitect.prompts.resolver.strategy import (
    ResolutionConfig,
    MultiSpaceResolutionStrategy,
    SingleSpaceResolutionStrategy,
)


class TestResolutionConfig:
    """Tests for ResolutionConfig."""

    def test_create_minimal_config(self):
        """Test creating config with only required fields."""
        config = ResolutionConfig(space_id="space-1")
        assert config.space_id == "space-1"
        assert config.included_spaces == []
        assert config.default_space_id is None
        assert config.shared_space_id is None
        assert config.max_generation_depth == 3

    def test_create_full_config(self):
        """Test creating config with all fields."""
        config = ResolutionConfig(
            space_id="space-1",
            included_spaces=["space-2", "space-3"],
            default_space_id="default-space",
            shared_space_id="shared-space",
            max_generation_depth=5,
        )
        assert config.space_id == "space-1"
        assert config.included_spaces == ["space-2", "space-3"]
        assert config.default_space_id == "default-space"
        assert config.shared_space_id == "shared-space"
        assert config.max_generation_depth == 5

    def test_config_to_dict(self):
        """Test serialization."""
        config = ResolutionConfig(
            space_id="space-1",
            included_spaces=["space-2"],
        )
        data = config.to_dict()
        assert data["space_id"] == "space-1"
        assert data["included_spaces"] == ["space-2"]
        assert "max_generation_depth" in data

    def test_config_from_dict(self):
        """Test deserialization."""
        data = {
            "space_id": "space-1",
            "included_spaces": ["space-2", "space-3"],
            "default_space_id": "default",
            "shared_space_id": "shared",
            "max_generation_depth": 4,
        }
        config = ResolutionConfig.from_dict(data)
        assert config.space_id == "space-1"
        assert config.included_spaces == ["space-2", "space-3"]
        assert config.default_space_id == "default"
        assert config.shared_space_id == "shared"
        assert config.max_generation_depth == 4


class TestMultiSpaceResolutionStrategy:
    """Tests for MultiSpaceResolutionStrategy."""

    def setup_method(self):
        """Setup strategy for each test."""
        self.strategy = MultiSpaceResolutionStrategy()

    def test_search_order_local_only(self):
        """Test search order with only local space."""
        config = ResolutionConfig(space_id="space-1")
        order = self.strategy.get_search_order(config)
        assert order == ["space-1"]

    def test_search_order_with_included(self):
        """Test search order with included spaces."""
        config = ResolutionConfig(
            space_id="space-1",
            included_spaces=["space-2", "space-3"],
        )
        order = self.strategy.get_search_order(config)
        assert order == ["space-1", "space-2", "space-3"]

    def test_search_order_with_default(self):
        """Test search order with default space."""
        config = ResolutionConfig(
            space_id="space-1",
            default_space_id="default-space",
        )
        order = self.strategy.get_search_order(config)
        assert order == ["space-1", "default-space"]

    def test_search_order_with_shared(self):
        """Test search order with shared space."""
        config = ResolutionConfig(
            space_id="space-1",
            shared_space_id="shared-space",
        )
        order = self.strategy.get_search_order(config)
        assert order == ["space-1", "shared-space"]

    def test_search_order_full_config(self):
        """Test full resolution order (FR-3.1)."""
        config = ResolutionConfig(
            space_id="local",
            included_spaces=["included-1", "included-2"],
            default_space_id="default",
            shared_space_id="shared",
        )
        order = self.strategy.get_search_order(config)
        # FR-3.1: Local, Included, Default, Shared
        assert order == ["local", "included-1", "included-2", "default", "shared"]

    def test_search_order_removes_duplicates(self):
        """Test that duplicates are removed."""
        config = ResolutionConfig(
            space_id="space-1",
            included_spaces=["space-2", "space-1", "space-3"],  # space-1 duplicate
            default_space_id="space-2",  # space-2 duplicate
        )
        order = self.strategy.get_search_order(config)
        # Should have each space only once, preserving first occurrence
        assert order == ["space-1", "space-2", "space-3"]
        assert len(order) == 3

    def test_search_order_preserves_included_order(self):
        """Test that included spaces order is preserved."""
        config = ResolutionConfig(
            space_id="space-1",
            included_spaces=["space-a", "space-b", "space-c"],
        )
        order = self.strategy.get_search_order(config)
        # Included spaces should appear in specified order
        assert order.index("space-a") < order.index("space-b")
        assert order.index("space-b") < order.index("space-c")

    def test_search_order_priority(self):
        """Test search order priority."""
        config = ResolutionConfig(
            space_id="local",
            included_spaces=["included"],
            default_space_id="default",
            shared_space_id="shared",
        )
        order = self.strategy.get_search_order(config)
        # Local has highest priority (index 0)
        assert order[0] == "local"
        # Shared has lowest priority (last index)
        assert order[-1] == "shared"


class TestSingleSpaceResolutionStrategy:
    """Tests for SingleSpaceResolutionStrategy."""

    def setup_method(self):
        """Setup strategy for each test."""
        self.strategy = SingleSpaceResolutionStrategy()

    def test_search_order_only_local(self):
        """Test that only local space is returned."""
        config = ResolutionConfig(
            space_id="space-1",
            included_spaces=["space-2", "space-3"],
            default_space_id="default",
            shared_space_id="shared",
        )
        order = self.strategy.get_search_order(config)
        assert order == ["space-1"]

    def test_search_order_ignores_other_spaces(self):
        """Test that other configured spaces are ignored."""
        config = ResolutionConfig(
            space_id="my-space",
            included_spaces=["ignored-1", "ignored-2"],
        )
        order = self.strategy.get_search_order(config)
        assert len(order) == 1
        assert order[0] == "my-space"
