# #region Test.Services.Mapping [C:3] [TYPE Module] [SEMANTICS test,mapping,superset,suggestions]
# @BRIEF Tests for mapping_service.py (services/mapping_service.py) — get_client, get_suggestions.
# @RELATION BINDS_TO -> [MappingService]

from pathlib import Path
import sys

sys.path.insert(0, str(Path(__file__).parent.parent / "src"))

from unittest.mock import AsyncMock, MagicMock, patch
import pytest


class MockEnvironment:
    def __init__(self, env_id, name="test-env"):
        self.id = env_id
        self.name = name
        self.username = "admin"
        self.password = "pass"
        self.url = "http://localhost:8080"
        self.verify_ssl = False
        self.timeout = 30


class TestGetMappingService:
    """MappingService — orchestrates DB fetching and fuzzy matching suggestions."""

    @pytest.fixture
    def config_manager(self):
        cm = MagicMock()
        cm.get_environments.return_value = [
            MockEnvironment("source-1", "Source"),
            MockEnvironment("target-1", "Target"),
        ]
        return cm

    @pytest.fixture
    def service(self, config_manager):
        from src.services.mapping_service import MappingService
        return MappingService(config_manager)

    def test_init(self, config_manager):
        from src.services.mapping_service import MappingService
        svc = MappingService(config_manager)
        assert svc.config_manager is config_manager

    def test_get_client_success(self, service):
        from src.core.superset_client import SupersetClient
        client = service._get_client("source-1")
        assert isinstance(client, SupersetClient)
        assert client.env.id == "source-1"

    def test_get_client_not_found(self, service):
        with pytest.raises(ValueError, match="Environment unknown-env not found"):
            service._get_client("unknown-env")

    @pytest.mark.asyncio
    async def test_get_suggestions_success(self, service):
        from src.services.mapping_service import MappingService
        source_dbs = [{"database_name": "sales_db", "id": 1}]
        target_dbs = [{"database_name": "sales", "id": 2}]

        with (
            patch.object(MappingService, "_get_client") as mock_get_client,
            patch("src.services.mapping_service.suggest_mappings") as mock_suggest,
        ):
            mock_source_client = MagicMock()
            mock_target_client = MagicMock()
            mock_source_client.get_databases_summary = AsyncMock(return_value=source_dbs)
            mock_target_client.get_databases_summary = AsyncMock(return_value=target_dbs)
            mock_get_client.side_effect = [mock_source_client, mock_target_client]
            mock_suggest.return_value = [{"source": "sales_db", "target": "sales", "score": 0.9}]

            result = await service.get_suggestions("source-1", "target-1")
            assert result == [{"source": "sales_db", "target": "sales", "score": 0.9}]
            mock_suggest.assert_called_once_with(source_dbs, target_dbs)

    @pytest.mark.asyncio
    async def test_get_suggestions_passes_envs_to_client(self, service):
        from src.services.mapping_service import MappingService
        with patch.object(MappingService, "_get_client") as mock_get_client:
            mock_client = MagicMock()
            mock_client.get_databases_summary = AsyncMock(return_value=[])
            mock_get_client.return_value = mock_client

            with patch("src.services.mapping_service.suggest_mappings", return_value=[]):
                result = await service.get_suggestions("source-1", "target-1")
                assert result == []
                assert mock_get_client.call_count == 2
# #endregion Test.MappingService
