#!/usr/bin/env node
/**
 * TIP Proxy Agent CLI
 *
 * Usage:
 *   tip-agent start --token TOKEN [--port 1080] [--max-gb 10] [--name "My Node"]
 *   tip-agent status
 *   tip-agent stop
 */
import { startAgent } from "./agent";
import { loadConfig, saveConfig, loadPid, clearPid } from "./config";

const AGENT_VERSION = "1.0.0";

function parseArgs(argv: string[]): Record<string, string> {
  const args: Record<string, string> = {};
  for (let i = 0; i < argv.length; i++) {
    const arg = argv[i];
    if (arg && arg.startsWith("--")) {
      const key = arg.slice(2);
      const next = argv[i + 1];
      if (next && !next.startsWith("--")) {
        args[key] = next;
        i++;
      } else {
        args[key] = "true";
      }
    }
  }
  return args;
}

function isProcessRunning(pid: number): boolean {
  try {
    process.kill(pid, 0);
    return true;
  } catch {
    return false;
  }
}

function cmdStart(rawArgs: string[]): void {
  const args = parseArgs(rawArgs);

  const token = args["token"];
  if (!token) {
    console.error("Error: --token is required");
    console.error("  tip-agent start --token YOUR_TOKEN [--port 1080] [--max-gb 10] [--name 'My Node']");
    process.exit(1);
  }

  const cfg = saveConfig({
    token,
    port: args["port"] ? parseInt(args["port"], 10) : 1080,
    maxGb: args["max-gb"] ? parseFloat(args["max-gb"]) : 10,
    name: args["name"] ?? undefined,
    serverUrl: args["server"] ?? "https://transceiver-db.context-x.org",
  });

  console.log(`\nTIP Proxy Agent v${AGENT_VERSION}`);
  console.log("==========================================");
  console.log(`  Token:    ${cfg.token.slice(0, 8)}...`);
  console.log(`  Port:     ${cfg.port}`);
  console.log(`  Max GB:   ${cfg.maxGb}`);
  console.log(`  Name:     ${cfg.name}`);
  console.log(`  Server:   ${cfg.serverUrl}`);
  console.log("==========================================\n");

  startAgent(cfg).catch((err) => {
    console.error("[agent] Fatal error:", err.message);
    process.exit(1);
  });
}

function cmdStatus(): void {
  const cfg = loadConfig();
  const pid = loadPid();

  if (!cfg || !pid) {
    console.log("TIP Agent: not running");
    process.exit(0);
  }

  const running = isProcessRunning(pid);
  console.log(`TIP Agent: ${running ? "RUNNING" : "STOPPED (stale PID)"}`);
  console.log(`  PID:     ${pid}`);
  console.log(`  Port:    ${cfg.port}`);
  console.log(`  Token:   ${cfg.token.slice(0, 8)}...`);
  console.log(`  Max GB:  ${cfg.maxGb}`);
  if (cfg.startedAt) {
    console.log(`  Started: ${cfg.startedAt}`);
  }

  if (!running) {
    clearPid();
  }
}

function cmdStop(): void {
  const pid = loadPid();

  if (!pid) {
    console.log("TIP Agent: not running");
    process.exit(0);
  }

  try {
    process.kill(pid, "SIGTERM");
    console.log(`TIP Agent (PID ${pid}) stopped.`);
    clearPid();
  } catch {
    console.log(`TIP Agent: process ${pid} not found (already stopped)`);
    clearPid();
  }
}

function printHelp(): void {
  console.log(`
TIP Proxy Agent v${AGENT_VERSION}
Contribute bandwidth to the TIP network, get free API access.

Usage:
  tip-agent start --token TOKEN [options]
  tip-agent status
  tip-agent stop

Commands:
  start     Start the proxy agent
  status    Show agent status
  stop      Stop the agent

Options:
  --token    TOKEN   Your TIP node token (required for start)
  --port     N       SOCKS5 listen port (default: 1080)
  --max-gb   N       Max bandwidth to donate in GB (default: 10)
  --name     NAME    Node name (default: hostname)
  --server   URL     TIP server URL (default: https://transceiver-db.context-x.org)

Example:
  tip-agent start --token abc123 --port 1080 --max-gb 10 --name "Home Node"
`);
}

const [, , command, ...rest] = process.argv;

switch (command) {
  case "start":
    cmdStart(rest);
    break;
  case "status":
    cmdStatus();
    break;
  case "stop":
    cmdStop();
    break;
  case "--help":
  case "-h":
  case "help":
    printHelp();
    break;
  default:
    if (command) {
      console.error(`Unknown command: ${command}`);
    }
    printHelp();
    process.exit(command ? 1 : 0);
}
