# #region Test.DatasetMapperExtra [C:2] [TYPE Module] [SEMANTICS test, dataset, mapper, metrics, edge]
# @BRIEF Extra tests for dataset_mapper.py — metrics handling in run_mapping (lines 193-206).
# @RELATION BINDS_TO -> [DatasetMapperModule]

from __future__ import annotations

import sys
from pathlib import Path
from unittest.mock import AsyncMock, MagicMock

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

import pytest


class TestDatasetMapperMetrics:
    """DatasetMapper.run_mapping — metrics transformation."""

    @pytest.mark.asyncio
    async def test_run_mapping_with_metrics(self):
        """run_mapping with dataset that has metrics updates them."""
        from src.core.utils.dataset_mapper import DatasetMapper

        mapper = DatasetMapper()
        mapper.get_sqllab_mappings = AsyncMock(
            return_value={"col1": "Column 1"}
        )
        client = AsyncMock()
        client.get_dataset = AsyncMock(
            return_value={
                "result": {
                    "table_name": "users",
                    "columns": [{"column_name": "col1", "verbose_name": None}],
                    "metrics": [
                        {"id": 1, "metric_name": "count", "expression": "COUNT(*)", "verbose_name": "Count"},
                        {"id": 2, "metric_name": "sum", "expression": "SUM(amount)", "verbose_name": None},
                    ],
                    "owners": [],
                    "database": {"id": 1},
                }
            }
        )
        client.update_dataset = AsyncMock(return_value={"result": "ok"})

        await mapper.run_mapping(
            superset_client=client,
            dataset_id=1,
            source="sqllab",
            sqllab_executor=MagicMock(),
            database_id=42,
        )
        client.update_dataset.assert_awaited_once()
        call_args = client.update_dataset.call_args
        payload = call_args[0][1]
        # Should have metrics in the payload
        assert "metrics" in payload
        # Metrics with None verbose_name should have the key stripped
        metric_names = [m["metric_name"] for m in payload["metrics"]]
        assert "count" in metric_names
        assert "sum" in metric_names

    @pytest.mark.asyncio
    async def test_run_mapping_skips_none_metric_fields(self):
        """Metrics with None fields have those keys stripped."""
        from src.core.utils.dataset_mapper import DatasetMapper

        mapper = DatasetMapper()
        mapper.get_sqllab_mappings = AsyncMock(
            return_value={"col1": "Column 1"}
        )
        client = AsyncMock()
        client.get_dataset = AsyncMock(
            return_value={
                "result": {
                    "table_name": "users",
                    "columns": [{"column_name": "col1", "verbose_name": None}],
                    "metrics": [
                        {"id": 1, "metric_name": "cnt", "expression": "COUNT(*)", "verbose_name": None, "description": None},
                    ],
                    "owners": [],
                    "database": {"id": 1},
                }
            }
        )
        client.update_dataset = AsyncMock(return_value={"result": "ok"})

        await mapper.run_mapping(
            superset_client=client,
            dataset_id=1,
            source="sqllab",
            sqllab_executor=MagicMock(),
            database_id=42,
        )
        call_args = client.update_dataset.call_args
        payload = call_args[0][1]
        metric = payload["metrics"][0]
        # None fields like `verbose_name` and `description` should be stripped
        assert "verbose_name" not in metric
        assert "description" not in metric
        assert metric["metric_name"] == "cnt"


class TestDatasetMapperNetworkEdge:
    """DatasetMapper edge cases — async_network integration."""

    @pytest.mark.asyncio
    async def test_run_mapping_with_async_client(self):
        """run_mapping with AsyncAPIClient (has async get_dataset/update_dataset)."""
        from src.core.utils.dataset_mapper import DatasetMapper

        mapper = DatasetMapper()
        mapper.get_sqllab_mappings = AsyncMock(
            return_value={"col1": "Column 1"}
        )
        client = AsyncMock()
        client.get_dataset = AsyncMock(
            return_value={
                "result": {
                    "table_name": "users",
                    "columns": [{"column_name": "col1", "verbose_name": None}],
                    "metrics": [],
                    "owners": [],
                    "database": {"id": 1},
                }
            }
        )
        client.update_dataset = AsyncMock(return_value={"result": "ok"})

        await mapper.run_mapping(
            superset_client=client,
            dataset_id=1,
            source="sqllab",
            sqllab_executor=MagicMock(),
            database_id=42,
        )
        client.update_dataset.assert_awaited_once()
# #endregion Test.DatasetMapperExtra
