#!/usr/bin/env -S npx --yes tsx
// =============================================================================
// session_start.ts — Start an async agent in a new (or existing) session
//
// Part of: .opencode/skills/auto-agents-system/scripts/
//
// Checks whether a session with the given tag already exists. If it does and
// --restart is not set, the existing session is reported without change. If it
// does not exist (or --restart is set), a new session is created with a title
// in "[TAG] display-name" format and the agent is launched asynchronously via
// prompt_async.
//
// USAGE:
//   session_start.ts --tag TAG --agent AGENT \
//     (--prompt TEXT | --prompt-file PATH) \
//     [--name DISPLAY_NAME] [--restart] [--server URL]
//
//   --tag TAG          Session tag, used as "[TAG] ..." prefix in the title.
//                      Must not include brackets (e.g. AUTO-IMP-ISSUE-42).
//   --agent AGENT      Name of the agent definition to invoke (e.g.
//                      task-implementor).
//   --prompt TEXT      Prompt text to send to the agent (suitable for short
//                      single-line prompts).
//   --prompt-file PATH Path to a file containing the prompt text. Preferred
//                      for long or multi-line prompts to avoid shell-escaping
//                      issues. Use this when writing prompts via the Edit tool.
//   --name NAME        Display name appended after the tag in the session title.
//                      Defaults to the agent name if omitted.
//   --restart          If a session with the same tag already exists, stop and
//                      replace it instead of reporting the existing one.
//   --server URL       OpenCode Server base URL (default: http://localhost:4096)
//
// OUTPUT (stdout): JSON object with fields:
//   session_id  string   ID of the new or existing session
//   status      string   'busy' | 'idle'
//   created     boolean  true if a new session was created, false if existing
//   message     string   Human-readable description of what happened
//
// DEPENDENCIES: Node.js >= 18 (native fetch), npx tsx (TypeScript execution)
// =============================================================================
import { fileURLToPath } from 'node:url';
import { readFileSync } from 'node:fs';
import {
  listSessions,
  createSession,
  getAllStatuses,
  promptAsync,
  deleteSession,
  extractTag,
  parseServerFlag,
  getFlag,
  hasFlag,
} from './session_api.ts';

// ─────────────────────────────────────────────────────────────────────────────
// MAIN
// ─────────────────────────────────────────────────────────────────────────────

async function main(): Promise<void> {
  const { server, rest } = parseServerFlag(process.argv);

  if (rest.includes('-h') || rest.includes('--help')) {
    printUsage();
    process.exit(0);
  }

  // ── Parse required arguments ───────────────────────────────────────────────
  const tag         = getFlag(rest, '--tag');
  const agentName   = getFlag(rest, '--agent');
  const promptText  = getFlag(rest, '--prompt');
  const promptFile  = getFlag(rest, '--prompt-file');
  const displayName = getFlag(rest, '--name');
  const restart     = hasFlag(rest, '--restart');

  if (!tag)       { process.stderr.write('ERROR: --tag is required\n');   process.exit(1); }
  if (!agentName) { process.stderr.write('ERROR: --agent is required\n'); process.exit(1); }

  if (!promptText && !promptFile) {
    process.stderr.write('ERROR: one of --prompt or --prompt-file is required\n');
    process.exit(1);
  }

  // Resolve the final prompt string
  let finalPrompt: string;
  if (promptFile) {
    try {
      finalPrompt = readFileSync(promptFile, 'utf-8');
    } catch (e) {
      process.stderr.write(`ERROR: Could not read prompt file "${promptFile}": ${e}\n`);
      process.exit(1);
    }
  } else {
    finalPrompt = promptText!;
  }

  // Build the session title: "[TAG] display-name"
  const name = displayName ?? agentName;
  const sessionTitle = `[${tag}] ${name}`;

  process.stderr.write(`Checking for existing session with tag [${tag}]…\n`);

  // ── Check if a session with this tag already exists ────────────────────────
  const sessions  = await listSessions(server);
  const statuses  = await getAllStatuses(server);
  const existing  = sessions.find(s => extractTag(s.title) === tag);

  if (existing && !restart) {
    const status = statuses[existing.id]?.type ?? 'idle';
    process.stderr.write(`Session "${existing.title}" already exists (${status}). Use --restart to replace.\n`);
    const result = {
      session_id: existing.id,
      status,
      created: false,
      message: `Existing session found: ${existing.title} [${status}]`,
    };
    process.stdout.write(JSON.stringify(result, null, 2) + '\n');
    return;
  }

  // ── Stop / delete existing session if --restart ────────────────────────────
  if (existing && restart) {
    process.stderr.write(`Removing existing session "${existing.title}" for restart…\n`);
    await deleteSession(server, existing.id);
    process.stderr.write(`Removed session ${existing.id}.\n`);
  }

  // ── Create a new session ───────────────────────────────────────────────────
  process.stderr.write(`Creating new session "${sessionTitle}"…\n`);
  const newSession = await createSession(server, sessionTitle);
  process.stderr.write(`Created session ${newSession.id}.\n`);

  // ── Launch the agent asynchronously ───────────────────────────────────────
  process.stderr.write(`Launching agent "${agentName}" in session ${newSession.id}…\n`);
  await promptAsync(server, newSession.id, agentName, finalPrompt);
  process.stderr.write(`Agent launched (prompt_async returned 204).\n`);

  const result = {
    session_id: newSession.id,
    status: 'busy',
    created: true,
    message: `Session created and agent "${agentName}" launched in ${newSession.id}`,
  };
  process.stdout.write(JSON.stringify(result, null, 2) + '\n');
}

function printUsage(): void {
  process.stderr.write(`\
Usage:
  session_start.ts --tag TAG --agent AGENT (--prompt TEXT | --prompt-file PATH) [OPTIONS]

REQUIRED:
  --tag TAG          Session tag without brackets (e.g. AUTO-IMP-ISSUE-42)
  --agent AGENT      Agent definition name to launch (e.g. task-implementor)
  --prompt TEXT      Prompt text to send to the agent
  --prompt-file PATH Path to file containing the prompt text (preferred for long prompts)

OPTIONAL:
  --name NAME        Display name portion of the session title (default: agent name)
  --restart          Replace any existing session with the same tag
  --server URL       OpenCode Server base URL (default: http://localhost:4096)
  -h, --help         Print this message and exit
`);
}

// ─────────────────────────────────────────────────────────────────────────────
// CLI ENTRY POINT
// ─────────────────────────────────────────────────────────────────────────────

if (process.argv[1] === fileURLToPath(import.meta.url)) {
  main().catch((err: unknown) => {
    process.stderr.write(`ERROR: ${err instanceof Error ? err.message : String(err)}\n`);
    process.exit(1);
  });
}
