"""Tests for Site Manager (core/site_manager.py) — registration and lookup."""

import pytest

from core.site_manager import SiteConfig, SiteManager

# --- SiteConfig Tests ---


class TestSiteConfig:
    """Test SiteConfig Pydantic model."""

    def test_basic_creation(self):
        """Should create a config with required fields."""
        config = SiteConfig(
            site_id="site1",
            plugin_type="wordpress",
            url="https://example.com",
        )
        assert config.site_id == "site1"
        assert config.plugin_type == "wordpress"
        assert config.url == "https://example.com"

    def test_alias_none_when_not_provided(self):
        """Alias should be None when not explicitly provided."""
        config = SiteConfig(site_id="site1", plugin_type="wordpress")
        # Pydantic V2: field_validator doesn't run on default values
        # get_display_name() handles the fallback to site_id
        assert config.alias is None
        assert config.get_display_name() == "site1"

    def test_custom_alias(self):
        """Custom alias should override default."""
        config = SiteConfig(site_id="site1", plugin_type="wordpress", alias="myblog")
        assert config.alias == "myblog"

    def test_get_full_id(self):
        """Full ID should be plugin_type_site_id."""
        config = SiteConfig(site_id="site1", plugin_type="wordpress")
        assert config.get_full_id() == "wordpress_site1"

    def test_get_display_name_with_alias(self):
        """Display name should prefer alias."""
        config = SiteConfig(site_id="site1", plugin_type="wordpress", alias="myblog")
        assert config.get_display_name() == "myblog"

    def test_get_display_name_without_alias(self):
        """Display name should fall back to site_id."""
        config = SiteConfig(site_id="site1", plugin_type="wordpress", alias=None)
        assert config.get_display_name() == "site1"

    def test_extra_fields_allowed(self):
        """Plugin-specific fields should be accepted."""
        config = SiteConfig(
            site_id="site1",
            plugin_type="wordpress",
            consumer_key="ck_123",
            consumer_secret="cs_456",
        )
        assert config.model_extra["consumer_key"] == "ck_123"

    def test_to_dict(self):
        """to_dict should include all fields."""
        config = SiteConfig(
            site_id="site1",
            plugin_type="wordpress",
            url="https://example.com",
        )
        d = config.to_dict()
        assert d["site_id"] == "site1"
        assert d["plugin_type"] == "wordpress"
        assert d["url"] == "https://example.com"


# --- SiteManager Tests ---


class TestSiteManagerRegistration:
    """Test site registration and lookup."""

    @pytest.fixture
    def manager(self):
        return SiteManager()

    def test_register_site(self, manager):
        """Should register a site and retrieve it by ID."""
        config = SiteConfig(site_id="site1", plugin_type="wordpress", url="https://example.com")
        manager.register_site(config)
        result = manager.get_site_config("wordpress", "site1")
        assert result.url == "https://example.com"

    def test_register_site_with_alias(self, manager):
        """Should be retrievable by alias."""
        config = SiteConfig(
            site_id="site1", plugin_type="wordpress", alias="myblog", url="https://example.com"
        )
        manager.register_site(config)
        result = manager.get_site_config("wordpress", "myblog")
        assert result.site_id == "site1"

    def test_site_not_found_raises(self, manager):
        """Should raise ValueError for unknown site."""
        config = SiteConfig(site_id="site1", plugin_type="wordpress")
        manager.register_site(config)
        with pytest.raises(ValueError, match="not configured"):
            manager.get_site_config("wordpress", "nonexistent")

    def test_unknown_plugin_type_raises(self, manager):
        """Should raise ValueError for unknown plugin type."""
        with pytest.raises(ValueError, match="No sites configured"):
            manager.get_site_config("unknown_plugin", "site1")

    def test_list_sites(self, manager):
        """Should list all site IDs and aliases."""
        config1 = SiteConfig(site_id="site1", plugin_type="wordpress", alias="blog1")
        config2 = SiteConfig(site_id="site2", plugin_type="wordpress", alias="blog2")
        manager.register_site(config1)
        manager.register_site(config2)
        sites = manager.list_sites("wordpress")
        assert "site1" in sites
        assert "site2" in sites
        assert "blog1" in sites
        assert "blog2" in sites

    def test_list_sites_empty_plugin(self, manager):
        """Should return empty list for unknown plugin type."""
        assert manager.list_sites("nonexistent") == []


class TestSiteManagerCounts:
    """Test counting and listing methods."""

    @pytest.fixture
    def populated_manager(self):
        manager = SiteManager()
        for i in range(3):
            config = SiteConfig(
                site_id=f"site{i+1}",
                plugin_type="wordpress",
                url=f"https://wp{i+1}.example.com",
            )
            manager.register_site(config)
        config = SiteConfig(
            site_id="repo1",
            plugin_type="gitea",
            url="https://git.example.com",
        )
        manager.register_site(config)
        return manager

    def test_get_count(self, populated_manager):
        assert populated_manager.get_count() == 4

    def test_get_count_by_type(self, populated_manager):
        counts = populated_manager.get_count_by_type()
        assert counts["wordpress"] == 3
        assert counts["gitea"] == 1

    def test_get_sites_by_type(self, populated_manager):
        wp_sites = populated_manager.get_sites_by_type("wordpress")
        assert len(wp_sites) == 3

    def test_get_sites_by_type_empty(self, populated_manager):
        assert populated_manager.get_sites_by_type("nonexistent") == []

    def test_list_all_sites(self, populated_manager):
        all_sites = populated_manager.list_all_sites()
        assert len(all_sites) == 4
        plugin_types = {s["plugin_type"] for s in all_sites}
        assert plugin_types == {"wordpress", "gitea"}

    def test_repr(self, populated_manager):
        r = repr(populated_manager)
        assert "SiteManager" in r
        assert "total=4" in r
