"""Helper library for CLI consistency Robot Framework tests.

Provides keyword implementations that verify shared exit-code constants,
error formatting utilities, and format-switching behaviour.
"""

from __future__ import annotations

import json
import subprocess
import sys


def get_exit_code_constants() -> dict[str, int]:
    """Return the CLI exit code constants as a dict."""
    from cleveragents.cli.constants import (
        EXIT_CONFLICT,
        EXIT_ERROR,
        EXIT_NOT_FOUND,
        EXIT_SUCCESS,
        EXIT_USAGE,
    )

    return {
        "EXIT_SUCCESS": EXIT_SUCCESS,
        "EXIT_ERROR": EXIT_ERROR,
        "EXIT_USAGE": EXIT_USAGE,
        "EXIT_NOT_FOUND": EXIT_NOT_FOUND,
        "EXIT_CONFLICT": EXIT_CONFLICT,
    }


def get_format_constants() -> dict[str, object]:
    """Return the CLI format constants as a dict."""
    from cleveragents.cli.constants import (
        DEFAULT_FORMAT,
        FORMAT_HELP,
        FORMAT_JSON,
        FORMAT_TABLE,
        FORMAT_TEXT,
        VALID_FORMATS,
    )

    return {
        "FORMAT_HELP": FORMAT_HELP,
        "DEFAULT_FORMAT": DEFAULT_FORMAT,
        "VALID_FORMATS": list(VALID_FORMATS),
        "FORMAT_TEXT": FORMAT_TEXT,
        "FORMAT_JSON": FORMAT_JSON,
        "FORMAT_TABLE": FORMAT_TABLE,
    }


def run_cli_command(python_path: str, *args: str) -> dict[str, object]:
    """Run a cleveragents CLI command and return rc, stdout, stderr."""
    cmd = [python_path, "-m", "cleveragents", *args]
    result = subprocess.run(
        cmd,
        capture_output=True,
        text=True,
        timeout=120,
    )
    return {
        "rc": result.returncode,
        "stdout": result.stdout,
        "stderr": result.stderr,
    }


def is_valid_json(text: str) -> bool:
    """Return True if *text* is valid JSON."""
    try:
        json.loads(text)
    except (json.JSONDecodeError, TypeError, ValueError):
        return False
    return True


def _run_error_script(python_path: str, script: str) -> dict[str, object]:
    """Execute a multi-line Python script in a subprocess."""
    result = subprocess.run(
        [python_path, "-c", script],
        capture_output=True,
        text=True,
        timeout=90,
    )
    return {
        "rc": result.returncode,
        "stdout": result.stdout,
        "stderr": result.stderr,
    }


def verify_cli_error_format(python_path: str) -> dict[str, object]:
    """Run a helper script that exercises cli_error and capture output."""
    target = "cleveragents.cli.errors._get_err_console"
    script = "\n".join(
        [
            "import sys",
            "from io import StringIO",
            "from unittest.mock import patch",
            "from rich.console import Console",
            "from cleveragents.cli.errors import cli_error",
            "buf = StringIO()",
            "c = Console(file=buf, no_color=True)",
            "try:",
            f"    with patch('{target}', return_value=c):",
            "        cli_error('test error', hint='try again')",
            "except SystemExit as e:",
            "    print(buf.getvalue(), end='')",
            "    sys.exit(e.code)",
        ]
    )
    return _run_error_script(python_path, script)


def verify_cli_not_found_format(python_path: str) -> dict[str, object]:
    """Run a helper script that exercises cli_not_found and capture output."""
    target = "cleveragents.cli.errors._get_err_console"
    script = "\n".join(
        [
            "import sys",
            "from io import StringIO",
            "from unittest.mock import patch",
            "from rich.console import Console",
            "from cleveragents.cli.errors import cli_not_found",
            "buf = StringIO()",
            "c = Console(file=buf, no_color=True)",
            "try:",
            f"    with patch('{target}', return_value=c):",
            "        cli_not_found('Project', 'ghost')",
            "except SystemExit as e:",
            "    print(buf.getvalue(), end='')",
            "    sys.exit(e.code)",
        ]
    )
    return _run_error_script(python_path, script)


def get_python_path() -> str:
    """Return the current Python interpreter path."""
    return sys.executable
