import {
  createBashTool,
  type ExtensionAPI,
  type ExtensionCommandContext,
  type ExtensionContext,
} from "@mariozechner/pi-coding-agent";
import { Type } from "@sinclair/typebox";
import { executePtyCommand } from "./pty-execute.ts";
import { ensureSpawnHelperExecutable } from "./spawn-helper.ts";

const bashLiveViewParams = Type.Object({
  command: Type.String({ description: "Command to execute" }),
  timeout: Type.Optional(Type.Number({ description: "Timeout in seconds" })),
  usePTY: Type.Optional(
    Type.Boolean({
      description:
        "Run inside a PTY with a live terminal widget the user can see while its running. Use this when you suspect the program being ran has interesting ansi progress output, like buildsystems.",
    })
  ),
});

ensureSpawnHelperExecutable();

async function runSlashCommand(args: string, ctx: ExtensionCommandContext) {
  const command = args.trim();
  if (!command) {
    ctx.ui.notify("Usage: /bash-pty <command>", "error");
    return;
  }
  const result = await executePtyCommand(
    `slash-${Date.now()}`,
    { command },
    new AbortController().signal,
    ctx as unknown as ExtensionContext
  );
  const text = result.content[0]?.type === "text" ? result.content[0].text : "(no output)";
  ctx.ui.notify(text.slice(0, 4000), "info");
}

export default function bashLiveView(pi: ExtensionAPI) {
  const originalBash = createBashTool(process.cwd());

  const registerTool = (name: string, label: string) => {
    pi.registerTool({
      name,
      label,
      description: `${originalBash.description} Supports optional usePTY=true live terminal rendering for terminal-style programs and richer progress UIs.`,
      parameters: bashLiveViewParams,
      async execute(toolCallId, params, signal, onUpdate, ctx) {
        if (params.usePTY !== true) {
          return originalBash.execute(toolCallId, params, signal, onUpdate);
        }
        return executePtyCommand(toolCallId, params, signal, ctx);
      },
    });
  };

  registerTool("bash_live_view", "bash_live_view");

  pi.registerCommand("bash-pty", {
    description: "Run a command through the PTY-backed bash path",
    handler: async (args, ctx) => {
      await runSlashCommand(args, ctx);
    },
  });
}
