#!/usr/bin/env node

/**
 * SnapBack VS Code Extension Fast Development Loop
 *
 * Optimized for rapid iteration (30 sec vs 10 min):
 * 1. Watches extension code with esbuild
 * 2. Auto-recompiles on changes
 * 3. Provides instructions for VS Code Extension Development Host
 *
 * Usage:
 *   node scripts/dev-ext.cjs
 *   # Or from root: pnpm --filter vscode dev:ext
 *
 * For auto-reload:
 *   1. Open apps/vscode in VS Code
 *   2. Press F5 to launch Extension Development Host
 *   3. Changes will auto-compile; press Cmd+R in host window to reload
 */

const { spawn, execSync } = require("node:child_process");
const path = require("node:path");
const fs = require("node:fs");

// ANSI colors
const colors = {
	reset: "\x1b[0m",
	bold: "\x1b[1m",
	dim: "\x1b[2m",
	green: "\x1b[32m",
	yellow: "\x1b[33m",
	blue: "\x1b[34m",
	cyan: "\x1b[36m",
	magenta: "\x1b[35m",
};

function log(msg, color = "reset") {
	const timestamp = new Date().toLocaleTimeString();
	console.log(`${colors.dim}[${timestamp}]${colors.reset} ${colors[color]}${msg}${colors.reset}`);
}

function logHeader() {
	console.log(`
${colors.cyan}${colors.bold}╔════════════════════════════════════════════════════════════╗
║        SnapBack Extension Fast Development Loop            ║
╚════════════════════════════════════════════════════════════╝${colors.reset}
`);

	console.log(`${colors.yellow}${colors.bold}Quick Start:${colors.reset}
  ${colors.dim}1.${colors.reset} Open ${colors.cyan}apps/vscode${colors.reset} in VS Code
  ${colors.dim}2.${colors.reset} Press ${colors.cyan}F5${colors.reset} to launch Extension Development Host
  ${colors.dim}3.${colors.reset} Make changes → auto-compile → ${colors.cyan}Cmd+R${colors.reset} to reload
`);

	console.log(`${colors.yellow}${colors.bold}Hot Keys in Development Host:${colors.reset}
  ${colors.cyan}Cmd+R${colors.reset}       Reload Extension
  ${colors.cyan}Cmd+Shift+P${colors.reset} Command Palette → "Developer: Reload Window"
`);
}

function checkDependencies() {
	const extensionRoot = process.cwd();
	const distPath = path.join(extensionRoot, "dist");

	// Ensure we're in the vscode extension directory
	const packageJsonPath = path.join(extensionRoot, "package.json");
	if (!fs.existsSync(packageJsonPath)) {
		console.error(`${colors.yellow}Error: Run this from apps/vscode directory${colors.reset}`);
		process.exit(1);
	}

	const pkg = JSON.parse(fs.readFileSync(packageJsonPath, "utf-8"));
	if (pkg.name !== "snapback-vscode") {
		console.error(`${colors.yellow}Error: This script must be run from apps/vscode${colors.reset}`);
		process.exit(1);
	}

	// Create dist directory if it doesn't exist
	if (!fs.existsSync(distPath)) {
		fs.mkdirSync(distPath, { recursive: true });
	}
}

function startWatcher() {
	const extensionRoot = process.cwd();
	const esbuildConfig = path.join(extensionRoot, "esbuild.config.cjs");

	log("Starting esbuild watch mode...", "cyan");
	log("Watching for changes in src/**/*.ts", "dim");

	const watcher = spawn("node", [esbuildConfig, "--watch"], {
		cwd: extensionRoot,
		stdio: ["inherit", "pipe", "pipe"],
		env: { ...process.env, FORCE_COLOR: "1" },
	});

	let compileCount = 0;

	watcher.stdout.on("data", (data) => {
		const output = data.toString().trim();
		if (output.includes("build finished")) {
			compileCount++;
			log(`✓ Build #${compileCount} complete (Cmd+R to reload)`, "green");
		} else if (output.includes("watching")) {
			log("Watching for changes...", "dim");
		} else if (output) {
			console.log(output);
		}
	});

	watcher.stderr.on("data", (data) => {
		const output = data.toString().trim();
		if (output.includes("error")) {
			log(`✗ Build error: ${output}`, "yellow");
		} else if (output) {
			console.error(colors.yellow + output + colors.reset);
		}
	});

	watcher.on("close", (code) => {
		if (code !== 0) {
			log(`Watcher exited with code ${code}`, "yellow");
		}
	});

	// Handle graceful shutdown
	process.on("SIGINT", () => {
		log("\nShutting down...", "dim");
		watcher.kill();
		process.exit(0);
	});

	process.on("SIGTERM", () => {
		watcher.kill();
		process.exit(0);
	});
}

function main() {
	logHeader();
	checkDependencies();
	startWatcher();
}

main();
