"""统一 CLI 测试。

验证子命令路由 + argparse 解析正确。
"""

from __future__ import annotations

import sys
from unittest.mock import patch

from a_share_cli.main import main


def _run(args: str) -> int:
    with patch.object(sys, "argv", ["a-share", *args.split()]):
        try:
            return main()
        except SystemExit as e:
            return e.code if isinstance(e.code, int) else 1


def test_no_args_shows_help() -> None:
    rc = _run("")
    assert rc == 0


def test_crawl_default() -> None:
    with patch("a_share_cli.main.cmd_crawl", return_value=0) as mock:
        _run("crawl")
    mock.assert_called_once()


def test_crawl_with_source() -> None:
    with patch("a_share_cli.main.cmd_crawl", return_value=0) as mock:
        _run("crawl --source cls")
    args = mock.call_args[0][0]
    assert args.source == "cls"


def test_extract_with_date() -> None:
    with patch("a_share_cli.main.cmd_extract", return_value=0) as mock:
        _run("extract --date 20260616 --source sina")
    args = mock.call_args[0][0]
    assert args.date == "20260616"
    assert args.source == "sina"


def test_events_with_provider() -> None:
    with patch("a_share_cli.main.cmd_events", return_value=0) as mock:
        _run("events --provider qwen --limit 5")
    args = mock.call_args[0][0]
    assert args.provider == "qwen"
    assert args.limit == 5


def test_search_default() -> None:
    with patch("a_share_cli.main.cmd_search", return_value=0) as mock:
        _run("search 宁德时代")
    args = mock.call_args[0][0]
    assert args.query == "宁德时代"
    assert args.top == 10


def test_search_with_filters() -> None:
    with patch("a_share_cli.main.cmd_search", return_value=0) as mock:
        _run("search 芯片 --source cls --sentiment positive --min-importance 3 --top 5")
    args = mock.call_args[0][0]
    assert args.query == "芯片"
    assert args.source == "cls"
    assert args.sentiment == "positive"
    assert args.min_importance == 3
    assert args.top == 5


def test_search_with_stock() -> None:
    with patch("a_share_cli.main.cmd_search", return_value=0) as mock:
        _run("search 重大合同 --stock 300750.sz")
    args = mock.call_args[0][0]
    assert args.stock == "300750.sz"


def test_pipeline_once() -> None:
    with patch("a_share_cli.main.cmd_pipeline", return_value=0) as mock:
        _run("pipeline --once --steps crawler,extractor")
    args = mock.call_args[0][0]
    assert args.once is True
    assert args.steps == "crawler,extractor"


def test_status() -> None:
    with patch("a_share_cli.main.cmd_status", return_value=0) as mock:
        _run("status")
    mock.assert_called_once()
