# #region Test.SupersetClient.Datasets.Edge [C:3] [TYPE Module] [SEMANTICS test, superset, datasets, mixin, edge]
# @BRIEF Edge case tests for SupersetDatasetsMixin — get_datasets_summary, get_dataset_linked_dashboard_count, get_dataset_detail edge cases.
# @RELATION BINDS_TO -> [SupersetDatasetsMixin]

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

from unittest.mock import AsyncMock, MagicMock

import pytest


class TestGetDatasetsSummary:
    @pytest.mark.asyncio
    async def test_summary(self):
        from src.core.superset_client._datasets import SupersetDatasetsMixin
        mixin = SupersetDatasetsMixin()
        mixin.get_datasets = AsyncMock(return_value=(2, [
            {"id": 1, "table_name": "orders", "schema": "public", "database": {"database_name": "Main"}},
            {"id": 2, "table_name": "users", "schema": "public"},  # no database key → fallback to Unknown
        ]))
        result = await mixin.get_datasets_summary()
        assert len(result) == 2
        assert result[0]["database"] == "Main"
        assert result[1]["database"] == "Unknown"


class TestGetDatasetLinkedDashboardCount:
    @pytest.mark.asyncio
    async def test_with_dashboards_in_response(self):
        from src.core.superset_client._datasets import SupersetDatasetsMixin
        mixin = SupersetDatasetsMixin()
        mixin.client = AsyncMock()
        mixin.client.request.return_value = {"dashboards": [{"id": 1}, {"id": 2}]}
        count = await mixin.get_dataset_linked_dashboard_count(1)
        assert count == 2

    @pytest.mark.asyncio
    async def test_with_result_key(self):
        from src.core.superset_client._datasets import SupersetDatasetsMixin
        mixin = SupersetDatasetsMixin()
        mixin.client = AsyncMock()
        mixin.client.request.return_value = {"result": {"dashboards": [{"id": 1}]}}
        count = await mixin.get_dataset_linked_dashboard_count(1)
        assert count == 1

    @pytest.mark.asyncio
    async def test_non_dict_response(self):
        from src.core.superset_client._datasets import SupersetDatasetsMixin
        mixin = SupersetDatasetsMixin()
        mixin.client = AsyncMock()
        mixin.client.request.return_value = "not_a_dict"
        count = await mixin.get_dataset_linked_dashboard_count(1)
        assert count == 0

    @pytest.mark.asyncio
    async def test_exception_returns_zero(self):
        from src.core.superset_client._datasets import SupersetDatasetsMixin
        mixin = SupersetDatasetsMixin()
        mixin.client = AsyncMock()
        mixin.client.request.side_effect = Exception("API error")
        count = await mixin.get_dataset_linked_dashboard_count(1)
        assert count == 0

    @pytest.mark.asyncio
    async def test_empty_dashboards(self):
        from src.core.superset_client._datasets import SupersetDatasetsMixin
        mixin = SupersetDatasetsMixin()
        mixin.client = AsyncMock()
        mixin.client.request.return_value = {"dashboards": []}
        count = await mixin.get_dataset_linked_dashboard_count(1)
        assert count == 0

    @pytest.mark.asyncio
    async def test_unknown_structure(self):
        from src.core.superset_client._datasets import SupersetDatasetsMixin
        mixin = SupersetDatasetsMixin()
        mixin.client = AsyncMock()
        mixin.client.request.return_value = {"other": "data"}
        count = await mixin.get_dataset_linked_dashboard_count(1)
        assert count == 0


class TestGetDatasetDetail:
    @pytest.mark.asyncio
    async def test_column_with_none_id_skipped(self):
        from src.core.superset_client._datasets import SupersetDatasetsMixin
        mixin = SupersetDatasetsMixin()
        mixin.get_dataset = AsyncMock(return_value={
            "result": {
                "columns": [
                    {"id": None, "column_name": "skip_me"},
                    {"id": 2, "column_name": "keep_me"},
                ],
                "metrics": [],
                "sql": "SELECT 1",
                "database": {"id": 1, "backend": "postgresql"},
            }
        })
        mixin.client = MagicMock()
        mixin.client.request = AsyncMock(return_value={"dashboards": [{"id": 1, "dashboard_title": "Dash"}]})
        detail = await mixin.get_dataset_detail(1)
        assert len(detail["columns"]) == 1
        assert detail["columns"][0]["name"] == "keep_me"

    @pytest.mark.asyncio
    async def test_metric_with_none_id_skipped(self):
        from src.core.superset_client._datasets import SupersetDatasetsMixin
        mixin = SupersetDatasetsMixin()
        mixin.get_dataset = AsyncMock(return_value={
            "result": {
                "columns": [],
                "metrics": [
                    {"id": None, "metric_name": "skip"},
                    {"id": 5, "metric_name": "keep"},
                ],
                "sql": "",
                "database": {"id": 1},
            }
        })
        mixin.client = MagicMock()
        mixin.client.request = AsyncMock(return_value={"dashboards": []})
        detail = await mixin.get_dataset_detail(1)
        assert len(detail["metrics"]) == 1
        assert detail["metrics"][0]["metric_name"] == "keep"

    @pytest.mark.asyncio
    async def test_dashboard_with_none_id_skipped(self):
        from src.core.superset_client._datasets import SupersetDatasetsMixin
        mixin = SupersetDatasetsMixin()
        mixin.get_dataset = AsyncMock(return_value={
            "result": {
                "columns": [], "metrics": [], "sql": "",
                "database": {"id": 1, "backend": "postgresql"},
            }
        })
        mixin.client = MagicMock()
        mixin.client.request = AsyncMock(return_value={
            "dashboards": [{"id": None, "dashboard_title": "Skip"}]
        })
        detail = await mixin.get_dataset_detail(1)
        assert len(detail["linked_dashboards"]) == 0

    @pytest.mark.asyncio
    async def test_dashboard_int_id(self):
        from src.core.superset_client._datasets import SupersetDatasetsMixin
        mixin = SupersetDatasetsMixin()
        mixin.get_dataset = AsyncMock(return_value={
            "result": {
                "columns": [], "metrics": [], "sql": "",
                "database": {"id": 1, "backend": "postgresql"},
            }
        })
        mixin.client = MagicMock()
        mixin.client.request = AsyncMock(return_value={
            "dashboards": [
                {"id": 10, "dashboard_title": "Good"},
                {"id": None, "dashboard_title": "Skip"},
            ]
        })
        detail = await mixin.get_dataset_detail(1)
        assert len(detail["linked_dashboards"]) == 1

    @pytest.mark.asyncio
    async def test_dashboards_from_result(self):
        from src.core.superset_client._datasets import SupersetDatasetsMixin
        mixin = SupersetDatasetsMixin()
        mixin.get_dataset = AsyncMock(return_value={
            "result": {"columns": [], "metrics": [], "sql": "", "database": {"id": 1}}
        })
        mixin.client = MagicMock()
        # Use the result key path
        mixin.client.request = AsyncMock(return_value={
            "result": {"dashboards": {"result": [{"id": 1}]}}
        })
        detail = await mixin.get_dataset_detail(1)
        assert len(detail["linked_dashboards"]) == 1

    @pytest.mark.asyncio
    async def test_dashboards_api_exception(self):
        from src.core.superset_client._datasets import SupersetDatasetsMixin
        mixin = SupersetDatasetsMixin()
        mixin.get_dataset = AsyncMock(return_value={
            "result": {"columns": [], "metrics": [], "sql": "", "database": {"id": 1}}
        })
        mixin.client = MagicMock()
        mixin.client.request.side_effect = Exception("API error")
        detail = await mixin.get_dataset_detail(1)
        assert detail["linked_dashboards"] == []

    @pytest.mark.asyncio
    async def test_result_not_in_response_structure(self):
        """get_dataset returns data without 'result' key."""
        from src.core.superset_client._datasets import SupersetDatasetsMixin
        mixin = SupersetDatasetsMixin()
        mixin.get_dataset = AsyncMock(return_value={
            "id": 1, "columns": [{"id": 1, "column_name": "a"}],
            "metrics": [], "sql": "", "database": {"id": 1},
        })
        mixin.client = MagicMock()
        mixin.client.request = AsyncMock(return_value={"dashboards": []})
        detail = await mixin.get_dataset_detail(1)
        assert detail["id"] == 1
        assert len(detail["columns"]) == 1

    @pytest.mark.asyncio
    async def test_as_bool_edge_cases(self):
        """as_bool handles various input types."""
        from src.core.superset_client._datasets import SupersetDatasetsMixin
        mixin = SupersetDatasetsMixin()
        mixin.get_dataset = AsyncMock(return_value={
            "result": {
                "columns": [
                    {"id": 1, "column_name": "c1", "is_dttm": "true", "is_active": "yes"},
                    {"id": 2, "column_name": "c2", "is_dttm": "false", "is_active": "no"},
                ],
                "metrics": [], "sql": "", "database": {"id": 1},
            }
        })
        mixin.client = MagicMock()
        mixin.client.request = AsyncMock(return_value={"dashboards": []})
        detail = await mixin.get_dataset_detail(1)
        cols = {c["name"]: c for c in detail["columns"]}
        assert cols["c1"]["is_dttm"] is True
        assert cols["c2"]["is_dttm"] is False

    @pytest.mark.asyncio
    async def test_database_backend_fallback(self):
        """Uses engine as fallback for database_backend."""
        from src.core.superset_client._datasets import SupersetDatasetsMixin
        mixin = SupersetDatasetsMixin()
        mixin.get_dataset = AsyncMock(return_value={
            "result": {
                "columns": [], "metrics": [], "sql": "",
                "database": {"id": 1, "engine": "postgresql"},
            }
        })
        mixin.client = MagicMock()
        mixin.client.request = AsyncMock(return_value={"dashboards": []})
        detail = await mixin.get_dataset_detail(1)
        assert detail["database_backend"] == "postgresql"
# #endregion Test.SupersetClient.Datasets.Edge
