# -*- coding: utf-8 -*-
"""TaskRegistry 单元测试 — 验证 TaskMeta 元数据注册与查询"""
import pytest
from orchestration.task_registry import TaskRegistry, TaskMeta


# ── 辅助：用作注册的假任务类 ──────────────────────────────────

class _FakeTask:
    """占位任务类，用于测试注册"""
    def __init__(self, config, db_connection, api_client, logger):
        self.config = config


class _AnotherFakeTask:
    def __init__(self, config, db_connection, api_client, logger):
        pass


# ── fixtures ──────────────────────────────────────────────────

@pytest.fixture
def registry():
    return TaskRegistry()


# ── register + get_metadata ───────────────────────────────────

class TestRegisterAndMetadata:
    """注册与元数据查询"""

    def test_register_with_defaults(self, registry):
        """仅传 task_code + task_class 时，元数据使用默认值（向后兼容）"""
        registry.register("MY_TASK", _FakeTask)
        meta = registry.get_metadata("MY_TASK")
        assert meta is not None
        assert meta.task_class is _FakeTask
        assert meta.requires_db_config is True
        assert meta.layer is None
        assert meta.task_type == "etl"

    def test_register_with_full_metadata(self, registry):
        """传入完整元数据"""
        registry.register(
            "ODS_ORDERS", _FakeTask,
            requires_db_config=True, layer="ODS", task_type="etl",
        )
        meta = registry.get_metadata("ODS_ORDERS")
        assert meta.layer == "ODS"
        assert meta.task_type == "etl"

    def test_register_utility_task(self, registry):
        """工具类任务：requires_db_config=False"""
        registry.register(
            "INIT_SCHEMA", _FakeTask,
            requires_db_config=False, task_type="utility",
        )
        meta = registry.get_metadata("INIT_SCHEMA")
        assert meta.requires_db_config is False
        assert meta.task_type == "utility"

    def test_case_insensitive_lookup(self, registry):
        """task_code 大小写不敏感"""
        registry.register("my_task", _FakeTask)
        assert registry.get_metadata("MY_TASK") is not None
        assert registry.get_metadata("my_task") is not None

    def test_get_metadata_unknown_returns_none(self, registry):
        """查询未注册的任务返回 None"""
        assert registry.get_metadata("NONEXISTENT") is None


# ── create_task（接口不变）────────────────────────────────────

class TestCreateTask:

    def test_create_task_returns_instance(self, registry):
        registry.register("MY_TASK", _FakeTask)
        task = registry.create_task("MY_TASK", {"k": "v"}, None, None, None)
        assert isinstance(task, _FakeTask)
        assert task.config == {"k": "v"}

    def test_create_task_unknown_raises(self, registry):
        with pytest.raises(ValueError, match="未知的任务类型"):
            registry.create_task("NOPE", None, None, None, None)


# ── get_tasks_by_layer ────────────────────────────────────────

class TestGetTasksByLayer:

    def test_returns_matching_tasks(self, registry):
        registry.register("A", _FakeTask, layer="ODS")
        registry.register("B", _AnotherFakeTask, layer="ODS")
        registry.register("C", _FakeTask, layer="DWD")
        result = registry.get_tasks_by_layer("ODS")
        assert set(result) == {"A", "B"}

    def test_case_insensitive_layer(self, registry):
        registry.register("X", _FakeTask, layer="dws")
        assert registry.get_tasks_by_layer("DWS") == ["X"]

    def test_no_match_returns_empty(self, registry):
        registry.register("A", _FakeTask, layer="ODS")
        assert registry.get_tasks_by_layer("INDEX") == []

    def test_none_layer_excluded(self, registry):
        """layer=None 的任务不会被任何层查询返回"""
        registry.register("UTIL", _FakeTask)  # layer 默认 None
        assert registry.get_tasks_by_layer("ODS") == []


# ── is_utility_task ───────────────────────────────────────────

class TestIsUtilityTask:

    def test_utility_task(self, registry):
        registry.register("INIT", _FakeTask, requires_db_config=False)
        assert registry.is_utility_task("INIT") is True

    def test_normal_task(self, registry):
        registry.register("ETL", _FakeTask, requires_db_config=True)
        assert registry.is_utility_task("ETL") is False

    def test_unknown_task(self, registry):
        assert registry.is_utility_task("NOPE") is False


# ── get_all_task_codes（接口不变）──────────────────────────────

class TestGetAllTaskCodes:

    def test_returns_all_codes(self, registry):
        registry.register("A", _FakeTask)
        registry.register("B", _AnotherFakeTask)
        assert set(registry.get_all_task_codes()) == {"A", "B"}

    def test_empty_registry(self, registry):
        assert registry.get_all_task_codes() == []
