"""Helper script for cli_global_options.robot integration tests.

Each sub-command verifies one end-to-end behaviour of the new global CLI
options (--data-dir, --config-path, -v) introduced by issue #6785.
"""

from __future__ import annotations

import os
import sys
import tempfile
from pathlib import Path
from unittest.mock import patch

# ---------------------------------------------------------------------------
# Helpers
# ---------------------------------------------------------------------------


def _invoke(args: list[str]) -> tuple[int, str]:
    """Invoke the Typer app and return (exit_code, combined_output)."""
    from typer.testing import CliRunner

    from cleveragents.cli.main import app

    runner = CliRunner()
    result = runner.invoke(app, args, catch_exceptions=True)
    output = result.output or ""
    return result.exit_code, output


# ---------------------------------------------------------------------------
# Test cases (sub-commands)
# ---------------------------------------------------------------------------


def test_data_dir_accepted() -> None:
    with tempfile.TemporaryDirectory() as tmp:
        code, output = _invoke(["--data-dir", tmp, "version"])
        assert code == 0, f"Expected exit 0, got {code}. Output: {output}"
    print("cli-global-options-data-dir-accepted-ok")


def test_config_path_accepted() -> None:
    with tempfile.NamedTemporaryFile(suffix=".toml", delete=False) as tmp:
        tmp.write(b"# test config\n")
        tmp_path = tmp.name
    try:
        code, output = _invoke(["--config-path", tmp_path, "version"])
        assert code == 0, f"Expected exit 0, got {code}. Output: {output}"
        print("cli-global-options-config-path-accepted-ok")
    finally:
        os.unlink(tmp_path)


def test_verbosity_accepted() -> None:
    code, output = _invoke(["-v", "version"])
    assert code == 0, f"Expected exit 0, got {code}. Output: {output}"
    print("cli-global-options-verbosity-accepted-ok")


def test_combined_options() -> None:
    with tempfile.TemporaryDirectory() as tmp_dir:
        with tempfile.NamedTemporaryFile(suffix=".toml", delete=False) as tmp_cfg:
            tmp_cfg.write(b"# test\n")
            tmp_cfg_path = tmp_cfg.name
        try:
            code, output = _invoke(
                [
                    "--data-dir",
                    tmp_dir,
                    "--config-path",
                    tmp_cfg_path,
                    "version",
                ]
            )
            assert code == 0, f"Expected exit 0, got {code}. Output: {output}"
            print("cli-global-options-combined-ok")
        finally:
            os.unlink(tmp_cfg_path)


def test_data_dir_override() -> None:
    """Verify --data-dir sets CLEVERAGENTS_DATA_DIR env var during invocation."""
    with tempfile.TemporaryDirectory() as tmp:
        code, output = _invoke(["--data-dir", tmp, "version"])
        assert code == 0, f"Expected exit 0, got {code}. Output: {output}"

        # Verify the env var was set to (or derived from) the tmp dir
        env_val = os.environ.get("CLEVERAGENTS_DATA_DIR")
        if env_val:
            resolved_env = str(Path(env_val).resolve())
            resolved_tmp = str(Path(tmp).resolve())
            assert resolved_env == resolved_tmp, (
                f"CLEVERAGENTS_DATA_DIR={env_val!r} != {tmp!r}"
            )

    print("cli-global-options-data-dir-override-ok")


def test_config_path_override() -> None:
    """Verify --config-path sets CLEVERAGENTS_CONFIG_PATH env var during invocation."""
    with tempfile.NamedTemporaryFile(suffix=".toml", delete=False) as tmp:
        tmp.write(b"# test\n")
        tmp_path = tmp.name
    try:
        code, output = _invoke(["--config-path", tmp_path, "version"])
        assert code == 0, f"Expected exit 0, got {code}. Output: {output}"
        env_val = os.environ.get("CLEVERAGENTS_CONFIG_PATH")
        if env_val:
            assert str(Path(env_val).resolve()) == str(Path(tmp_path).resolve()), (
                f"CLEVERAGENTS_CONFIG_PATH={env_val!r} != {tmp_path!r}"
            )
        print("cli-global-options-config-path-override-ok")
    finally:
        os.unlink(tmp_path)


def test_verbosity_levels() -> None:
    """Verify the verbosity count → log level mapping."""
    from unittest.mock import MagicMock

    from cleveragents.cli.formatting import OutputFormat
    from cleveragents.cli.main import main_callback

    expected_levels = {
        0: "CRITICAL",
        1: "ERROR",
        2: "WARNING",
        3: "INFO",
        4: "DEBUG",
        5: "DEBUG",
    }

    for count, expected in expected_levels.items():
        captured_levels: list[str] = []

        def _make_capture(levels: list[str]):  # type: ignore[no-untyped-def]
            def _capture(*, env: str = "development", log_level: str = "INFO") -> None:
                levels.append(log_level)

            return _capture

        mock_ctx = MagicMock()
        mock_ctx.obj = {}

        with patch(
            "cleveragents.config.logging.configure_structlog",
            side_effect=_make_capture(captured_levels),
        ):
            main_callback(
                ctx=mock_ctx,
                version=None,  # type: ignore[arg-type]
                show_secrets=False,
                fmt=OutputFormat.RICH,
                data_dir=None,
                config_path=None,
                verbose=count,
            )

        assert captured_levels, f"configure_structlog not called for count={count}"
        actual = captured_levels[-1].upper()
        assert actual == expected, (
            f"verbose={count}: expected log_level={expected!r}, got {actual!r}"
        )

    print("cli-global-options-verbosity-levels-ok")


# ---------------------------------------------------------------------------
# Entry point
# ---------------------------------------------------------------------------


_COMMANDS: dict[str, object] = {
    "data-dir-accepted": test_data_dir_accepted,
    "config-path-accepted": test_config_path_accepted,
    "verbosity-accepted": test_verbosity_accepted,
    "combined-options": test_combined_options,
    "data-dir-override": test_data_dir_override,
    "config-path-override": test_config_path_override,
    "verbosity-levels": test_verbosity_levels,
}


if __name__ == "__main__":
    if len(sys.argv) < 2:
        print("Usage: helper_cli_global_options.py <command>", file=sys.stderr)
        sys.exit(1)

    cmd = sys.argv[1]
    fn = _COMMANDS.get(cmd)
    if fn is None:
        print(f"Unknown command: {cmd}", file=sys.stderr)
        sys.exit(1)

    try:
        fn()  # type: ignore[call-arg]
    except Exception as exc:
        print(f"FAILED: {exc}", file=sys.stderr)
        import traceback

        traceback.print_exc(file=sys.stderr)
        sys.exit(1)
