"""Helper script for tdd_session_list_missing_db.robot smoke tests.

Each subcommand exercises the real DI path (no mocks) to reproduce bug #680.
Unlike the #554 helpers, these tests point ``CLEVERAGENTS_DATABASE_URL`` at
a **non-existent** database file to verify that the application handles a
missing database gracefully (auto-creating it or returning a clean error).

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.
"""

from __future__ import annotations

import os
import shutil
import sys
import tempfile
from collections.abc import Callable
from pathlib import Path

# Ensure local source tree AND robot/ directory are importable.
_ROOT = Path(__file__).resolve().parents[1]
_SRC = str(_ROOT / "src")
_ROBOT = str(_ROOT / "robot")
for _p in (_SRC, _ROBOT):
    if _p not in sys.path:
        sys.path.insert(0, _p)

from typer.testing import CliRunner  # noqa: E402

from cleveragents.application.container import reset_container  # noqa: E402
from cleveragents.cli.commands import session as session_mod  # noqa: E402
from cleveragents.cli.commands.session import app as session_app  # noqa: E402
from cleveragents.config.settings import Settings  # noqa: E402

runner = CliRunner()


# ---------------------------------------------------------------------------
# Setup / Teardown — missing-database variant
# ---------------------------------------------------------------------------


def setup_missing_db() -> str:
    """Prepare the environment with a database URL pointing to a non-existent file.

    Returns the path to the temp directory (caller must clean up).
    """
    session_mod._service = None
    reset_container()
    tmpdir = tempfile.mkdtemp(prefix="tdd_missing_db_680_")
    db_path = os.path.join(tmpdir, "nonexistent.db")
    os.environ["CLEVERAGENTS_DATABASE_URL"] = f"sqlite:///{db_path}"
    return tmpdir


def teardown_missing_db(tmpdir: str) -> None:
    """Clean up after a test."""
    session_mod._service = None
    os.environ.pop("CLEVERAGENTS_DATABASE_URL", None)
    reset_container()
    Settings._instance = None
    shutil.rmtree(tmpdir, ignore_errors=True)


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


def list_missing_db() -> None:
    """Invoke ``session list`` when no database file exists.

    Exits 0 with sentinel when the command succeeds (bug fixed).
    Exits 1 when the command fails (bug still present).
    """
    tmpdir = setup_missing_db()
    try:
        result = runner.invoke(session_app, ["list"])
        if result.exit_code == 0:
            print("tdd-session-list-missing-db-ok")
        else:
            print(
                f"session list failed with exit code {result.exit_code}",
                file=sys.stderr,
            )
            if result.exception:
                import traceback

                traceback.print_exception(
                    type(result.exception),
                    result.exception,
                    result.exception.__traceback__,
                    file=sys.stderr,
                )
            sys.exit(1)
    finally:
        teardown_missing_db(tmpdir)


def list_missing_db_json() -> None:
    """Invoke ``session list --format json`` when no database file exists.

    Exits 0 with sentinel when the command succeeds (bug fixed).
    Exits 1 when the command fails (bug still present).
    """
    tmpdir = setup_missing_db()
    try:
        result = runner.invoke(session_app, ["list", "--format", "json"])
        if result.exit_code == 0:
            print("tdd-session-list-missing-db-json-ok")
        else:
            print(
                f"session list --format json failed with exit code {result.exit_code}",
                file=sys.stderr,
            )
            sys.exit(1)
    finally:
        teardown_missing_db(tmpdir)


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

_COMMANDS: dict[str, Callable[[], None]] = {
    "list-missing-db": list_missing_db,
    "list-missing-db-json": list_missing_db_json,
}

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()
