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

Each subcommand exercises the ``plan correct`` CLI command with a
decision_id as the first positional argument and **no** ``--plan``
flag, forcing the code to auto-resolve the active plan via
``_resolve_active_plan_id()``.

The helper simulates the isolated-environment condition described in
bug #1025: the first ``get_container()`` call returns a container
with plans, but the second call (from ``_resolve_active_plan_id``)
returns a container with an empty plan list.

The helper reports the **real** outcome: it exits 0 and prints the
sentinel when the operation succeeds (bug is fixed), and exits 1
when the bug is still present.  The ``tdd_expected_fail_listener``
on the Robot side handles pass/fail inversion while the bug remains
open.

Bug: https://git.cleverthis.com/cleveragents/cleveragents-core/issues/1025
TDD: https://git.cleverthis.com/cleveragents/cleveragents-core/issues/1035
"""

from __future__ import annotations

import sys
from collections.abc import Callable
from pathlib import Path
from unittest.mock import patch

# Ensure local source tree is importable
_SRC = str(Path(__file__).resolve().parents[1] / "src")
if _SRC not in sys.path:
    sys.path.insert(0, _SRC)

# Ensure features package is importable for shared fixtures
_FEATURES = str(Path(__file__).resolve().parents[1])
if _FEATURES not in sys.path:
    sys.path.insert(0, _FEATURES)

from features.mocks.tdd_plan_correct_auto_resolve_fixtures import (  # noqa: E402
    DECISION_ID,
    PATCH_CONTAINER,
    PATCH_CORRECTION_SVC,
    build_cli_args,
    make_container_side_effects,
    make_correction_svc,
)
from typer.testing import CliRunner  # noqa: E402

from cleveragents.cli.commands.plan import app as plan_app  # noqa: E402

runner = CliRunner()


# ---------------------------------------------------------------------------
# Subcommands
# ---------------------------------------------------------------------------


def _run_plan_correct_auto_resolve(mode: str, sentinel: str) -> None:
    """Invoke ``plan correct <decision_id>`` without ``--plan``.

    Simulates the isolated-environment condition: the first
    ``get_container`` call returns a full container, the second
    returns an empty one.

    Exits 0 with *sentinel* when the command succeeds (bug fixed).
    Exits 1 when the bug is still present.

    Args:
        mode: The correction mode (``"revert"`` or ``"append"``).
        sentinel: The sentinel string to print on success.
    """
    correction_svc = make_correction_svc(DECISION_ID, mode=mode)
    side_effects = make_container_side_effects()

    args = build_cli_args(DECISION_ID, mode=mode)

    with (
        patch(PATCH_CORRECTION_SVC, return_value=correction_svc),
        patch(PATCH_CONTAINER, side_effect=side_effects),
    ):
        result = runner.invoke(plan_app, args)

    if result.exit_code != 0:
        print(
            f"Bug #1025: plan correct failed with exit code "
            f"{result.exit_code} when --plan was omitted.  "
            f"Auto-resolve failed in isolated environment.  "
            f"Output: {result.output}",
            file=sys.stderr,
        )
        sys.exit(1)

    # Verify the correction service was called
    correction_svc.request_correction.assert_called_once()
    print(sentinel)


def plan_correct_auto_resolve_revert() -> None:
    """Auto-resolve test with --mode revert."""
    _run_plan_correct_auto_resolve("revert", "tdd-plan-correct-auto-resolve-revert-ok")


def plan_correct_auto_resolve_append() -> None:
    """Auto-resolve test with --mode append."""
    _run_plan_correct_auto_resolve("append", "tdd-plan-correct-auto-resolve-append-ok")


# ---------------------------------------------------------------------------
# Dispatcher
# ---------------------------------------------------------------------------

_COMMANDS: dict[str, Callable[[], None]] = {
    "auto-resolve-revert": plan_correct_auto_resolve_revert,
    "auto-resolve-append": plan_correct_auto_resolve_append,
}

if __name__ == "__main__":
    if len(sys.argv) < 2 or sys.argv[1] not in _COMMANDS:
        print(
            f"Usage: {sys.argv[0]} <{'|'.join(_COMMANDS)}>",
            file=sys.stderr,
        )
        sys.exit(1)
    cmd = _COMMANDS[sys.argv[1]]
    cmd()
