import { spawn } from 'node:child_process';
import fs from 'node:fs/promises';
import path from 'node:path';

/**
 * Per-runner nginx map fragment cleanup. Mirrors the generator-side helper
 * (apps/generator/src/lib/deploy.ts) — when MCP_DOMAIN is set, the host
 * runs an inotify watcher over the map dir that reloads nginx on any
 * change. We remove the fragment here so the slug stops serving 502 the
 * moment the user deletes their server.
 *
 * No-op if MCP_DOMAIN isn't configured (legacy http://host:port URLs are
 * still in use). Idempotent — missing files are fine.
 */
const MCP_DOMAIN = process.env.MCP_DOMAIN ?? '';
const RUNNER_MAP_DIR = process.env.RUNNER_MAP_DIR ?? '/var/runner-map';

async function removeRunnerMapEntry(slug: string): Promise<void> {
  if (!MCP_DOMAIN || !slug) return;
  try {
    await fs.rm(path.join(RUNNER_MAP_DIR, `${slug}.conf`), { force: true });
  } catch {
    /* ignore — not critical */
  }
}

/**
 * Stop and remove a generated MCP container by container id.
 * Resolves regardless of outcome — failures are logged but never blocking.
 * Also drops the slug's nginx map fragment so the public URL stops 502'ing
 * the moment the container goes away.
 */
export async function stopContainer(
  containerId: string,
  slug?: string,
): Promise<{ ok: boolean; detail: string }> {
  if (!containerId || containerId.length < 4) {
    return { ok: false, detail: 'invalid_container_id' };
  }
  if (slug) await removeRunnerMapEntry(slug);
  return await new Promise<{ ok: boolean; detail: string }>((resolve) => {
    const child = spawn('docker', ['rm', '-f', containerId], {
      stdio: ['ignore', 'pipe', 'pipe'],
      shell: process.platform === 'win32',
    });
    let out = '';
    let err = '';
    child.stdout?.on('data', (d: Buffer) => {
      out += d.toString();
    });
    child.stderr?.on('data', (d: Buffer) => {
      err += d.toString();
    });
    child.on('error', () => resolve({ ok: false, detail: 'spawn_failed' }));
    child.on('close', (code) => {
      if (code === 0) {
        resolve({ ok: true, detail: out.trim() });
      } else {
        resolve({ ok: false, detail: err.trim() || `exit ${code}` });
      }
    });
  });
}
