/**
 * POST /api/connectors/<id>/sync-cli
 *
 * For connectors whose token doubles as a CLI tool's auth (currently
 * gitlab → `glab auth login`), write the Forge-stored token into the
 * CLI's own config so `glab` invocations from the user's terminal
 * use the same token Forge does for pipelines.
 *
 * Without this users hit "Forge says my MR pipeline 401s but I can run
 * glab fine in shell" — because shell glab has a stale revoked token
 * in ~/.config/glab-cli/config.yml while Forge has the fresh PAT.
 *
 * Currently only `gitlab` is supported. Other CLIs (gh) could be added
 * by extending the switch below.
 */

import { NextResponse } from 'next/server';
import { spawn } from 'node:child_process';
import { getInstalledConnector } from '@/lib/connectors/registry';

function runGlabLogin(host: string, token: string): Promise<{ ok: boolean; stderr: string }> {
  return new Promise((resolve) => {
    // Use --stdin so the token never appears in argv (visible in ps).
    const child = spawn('glab', ['auth', 'login', '--hostname', host, '--stdin'], {
      env: { ...process.env, NO_COLOR: '1' },
    });
    let stderr = '';
    child.stderr.on('data', (b: Buffer) => { stderr += b.toString(); });
    child.stdout.on('data', () => { /* swallow */ });
    child.on('error', (e) => resolve({ ok: false, stderr: `spawn failed: ${e.message}` }));
    child.on('exit', (code) => resolve({ ok: code === 0, stderr }));
    child.stdin.write(token + '\n');
    child.stdin.end();
  });
}

export async function POST(_req: Request, { params }: { params: Promise<{ id: string }> }) {
  const { id } = await params;

  if (id !== 'gitlab') {
    return NextResponse.json({ error: `sync-cli is only implemented for gitlab (got: ${id})` }, { status: 400 });
  }

  const conn = getInstalledConnector('gitlab');
  if (!conn || !conn.enabled) {
    return NextResponse.json({ error: 'gitlab connector is not installed or not enabled' }, { status: 404 });
  }
  const token = typeof conn.config?.token === 'string' ? conn.config.token.trim() : '';
  const baseUrl = typeof conn.config?.base_url === 'string' ? conn.config.base_url.trim() : '';
  if (!token) {
    return NextResponse.json({ error: 'gitlab connector has no token set — fill it in first, save, then sync' }, { status: 400 });
  }
  if (!baseUrl) {
    return NextResponse.json({ error: 'gitlab connector has no base_url set' }, { status: 400 });
  }
  let host: string;
  try {
    host = new URL(baseUrl).host;
  } catch {
    return NextResponse.json({ error: `base_url "${baseUrl}" is not a valid URL` }, { status: 400 });
  }

  const r = await runGlabLogin(host, token);
  if (!r.ok) {
    return NextResponse.json({
      ok: false,
      host,
      error: `glab auth login failed: ${r.stderr.trim() || '(no stderr)'}`,
      hint: 'Is `glab` installed and on PATH? Try `which glab` in a terminal.',
    }, { status: 500 });
  }
  return NextResponse.json({ ok: true, host, message: `glab auth login successful for ${host}` });
}
