"""Generic remote tool forwarding — tunnel local tool invocations to the remote GPU.

Provides a common pattern for forwarding system tools (nvidia-smi, nvcc, etc.)
to the remote machine via SSH.  Each tool gets a thin bash shim in the venv's
``bin/`` directory (written by :func:`specter_cli.venv.patch_venv`), which
calls::

    python.specter-original -m specter_cli.forward <tool> [args...]

The forwarding function handles:

- Config loading (host, port, key from ``.specter.json``)
- SSH command building with ControlMaster pooling
- PTY allocation for interactive tools (``nvidia-smi -l 1``)
- Signal forwarding (Ctrl+C cleanly stops the remote tool)
- Exit code passthrough
"""

from __future__ import annotations

import sys

from specter_cli.config import load_remote_config
from specter_cli.ssh_config import exec_ssh_passthrough, ssh_base_args


def forward_tool(tool: str, args: list[str]) -> int:
    """Forward a tool invocation to the remote GPU via SSH.

    Uses Popen with stdin/stdout/stderr passthrough so both one-shot
    tools (``nvidia-smi``) and continuous tools (``nvidia-smi -l 1``,
    ``nvidia-smi dmon``) work correctly.

    Parameters
    ----------
    tool:
        The tool name to run on the remote (e.g. ``nvidia-smi``).
    args:
        Arguments to pass to the tool.

    Returns
    -------
    The remote tool's exit code, or 127 if no active session.
    """
    import shlex

    config = load_remote_config()
    if not config or not config.get("host"):
        print(
            f"specter: no GPU session active — cannot forward {tool}.\n"
            f"  Run 'specter install <gpu>' first.",
            file=sys.stderr,
        )
        return 127  # Convention: "command not found"

    host = config["host"]
    user = config["user"]
    port = config.get("ssh_port", 22)
    key_path = config.get("key")

    # Build the remote command.
    remote_cmd = f"{tool} {shlex.join(args)}" if args else tool

    # Allocate PTY when stdin is a terminal — required for interactive
    # tools like `nvidia-smi -l 1` to stream output correctly.
    tty = sys.stdin.isatty()
    ssh_args = ssh_base_args(host, user, port=port, key_path=key_path, tty=tty)
    full_cmd = ["ssh", *ssh_args, remote_cmd]

    # Execute via SSH with full I/O passthrough and signal forwarding.
    return exec_ssh_passthrough(full_cmd)


def main() -> None:
    """Entry point: ``python -m specter_cli.forward <tool> [args...]``."""
    if len(sys.argv) < 2:
        print("Usage: python -m specter_cli.forward <tool> [args...]", file=sys.stderr)
        sys.exit(1)

    tool = sys.argv[1]
    args = sys.argv[2:]
    sys.exit(forward_tool(tool, args))


if __name__ == "__main__":
    main()
