# -*- coding: utf-8 -*-
"""CLI 参数解析单元测试

验证 --data-source 新参数、--pipeline-flow 弃用映射、
以及 build_cli_overrides 集成行为。

需求: 3.1, 3.3, 3.5
"""
import warnings
from argparse import Namespace
from unittest.mock import patch

import pytest

from cli.main import parse_args, resolve_data_source, build_cli_overrides


# ---------------------------------------------------------------------------
# 1. --data-source 新参数解析
# ---------------------------------------------------------------------------
class TestDataSourceArg:
    """--data-source 新参数测试"""

    @pytest.mark.parametrize("value", ["online", "offline", "hybrid"])
    def test_data_source_valid_values(self, value):
        with patch("sys.argv", ["cli", "--data-source", value]):
            args = parse_args()
        assert args.data_source == value

    def test_data_source_default_is_none(self):
        with patch("sys.argv", ["cli"]):
            args = parse_args()
        assert args.data_source is None


# ---------------------------------------------------------------------------
# 2. resolve_data_source() 弃用映射
# ---------------------------------------------------------------------------
class TestResolveDataSource:
    """resolve_data_source() 弃用映射测试"""

    def test_explicit_data_source_returns_directly(self):
        args = Namespace(data_source="online", pipeline_flow=None)
        assert resolve_data_source(args) == "online"

    def test_data_source_takes_priority_over_pipeline_flow(self):
        """--data-source 优先于 --pipeline-flow"""
        args = Namespace(data_source="online", pipeline_flow="FULL")
        assert resolve_data_source(args) == "online"


    @pytest.mark.parametrize(
        "flow, expected",
        [
            ("FULL", "hybrid"),
            ("FETCH_ONLY", "online"),
            ("INGEST_ONLY", "offline"),
        ],
    )
    def test_pipeline_flow_maps_with_deprecation_warning(self, flow, expected):
        """旧参数 --pipeline-flow 映射到正确的 data_source 并发出弃用警告"""
        args = Namespace(data_source=None, pipeline_flow=flow)
        with pytest.warns(DeprecationWarning, match="--pipeline-flow 已弃用"):
            result = resolve_data_source(args)
        assert result == expected

    def test_neither_arg_defaults_to_hybrid(self):
        """两个参数都未指定时，默认返回 hybrid"""
        args = Namespace(data_source=None, pipeline_flow=None)
        assert resolve_data_source(args) == "hybrid"


# ---------------------------------------------------------------------------
# 3. build_cli_overrides() 集成
# ---------------------------------------------------------------------------
class TestBuildCliOverrides:
    """build_cli_overrides() 集成测试"""

    def _make_args(self, **kwargs):
        """构造最小 Namespace，未指定的参数设为 None/False"""
        defaults = dict(
            store_id=None, tasks=None, dry_run=False,
            flow=None,
            processing_mode="increment_only",
            fetch_before_verify=False, verify_tables=None,
            window_split="none", lookback_hours=24, overlap_seconds=3600,
            pg_dsn=None, pg_host=None, pg_port=None, pg_name=None,
            pg_user=None, pg_password=None,
            api_base=None, api_token=None, api_timeout=None,
            api_page_size=None, api_retry_max=None,
            window_start=None, window_end=None,
            force_window_override=False,
            window_split_unit=None, window_split_days=None,
            window_compensation_hours=None,
            export_root=None, log_root=None,
            data_source=None, pipeline_flow=None,
            fetch_root=None, ingest_source=None, write_pretty_json=False,
            idle_start=None, idle_end=None, allow_empty_advance=False,
            force_full=False,
        )
        defaults.update(kwargs)
        return Namespace(**defaults)

    def test_data_source_online_sets_run_key(self):
        args = self._make_args(data_source="online")
        overrides = build_cli_overrides(args)
        assert overrides["run"]["data_source"] == "online"

    def test_pipeline_flow_sets_both_keys(self):
        """旧参数同时写入 pipeline.flow 和 run.data_source"""
        args = self._make_args(pipeline_flow="FULL")
        with warnings.catch_warnings():
            warnings.simplefilter("ignore", DeprecationWarning)
            overrides = build_cli_overrides(args)
        assert overrides["pipeline"]["flow"] == "FULL"
        assert overrides["run"]["data_source"] == "hybrid"

    def test_default_data_source_is_hybrid(self):
        """无 --data-source 也无 --pipeline-flow 时，run.data_source 默认 hybrid"""
        args = self._make_args()
        overrides = build_cli_overrides(args)
        assert overrides["run"]["data_source"] == "hybrid"


