import { NextRequest, NextResponse } from 'next/server';
import { execFile } from 'child_process';
import { promisify } from 'util';

const execFileAsync = promisify(execFile);

const COMMAND_ALLOWLIST = new Set([
  // Cross-platform (macOS + Linux)
  'git',
  'npm',
  'cat',
  'ls',
  'wc',
  'du',
  'df',
  'echo',
  'date',
  'head',
  'tail',
  'grep',
  'which',
  'ps',
  'uname',
  'whoami',
  // macOS
  'brew',
  // Linux / WSL2
  'free',
  'lscpu',
  'nvidia-smi',
  'dpkg',
  'apt',
]);

export async function POST(request: NextRequest) {
  try {
    const body = (await request.json()) as { command?: string; args?: string[] };
    const { command, args = [] } = body;

    if (!command) {
      return NextResponse.json({ error: 'Missing command' }, { status: 400 });
    }

    const extended =
      typeof window === 'undefined'
        ? (() => {
            try {
              const raw = process.env.LLM_COMMAND_ALLOWLIST;
              if (raw) return new Set(JSON.parse(raw) as string[]);
            } catch {
              /* ignore */
            }
            return new Set<string>();
          })()
        : new Set<string>();

    if (!COMMAND_ALLOWLIST.has(command) && !extended.has(command)) {
      return NextResponse.json(
        {
          error: `Command "${command}" is not in the allowlist`,
          allowed: [...COMMAND_ALLOWLIST, ...extended],
        },
        { status: 403 }
      );
    }

    const { stdout, stderr } = await execFileAsync(command, args, {
      timeout: 30_000,
      maxBuffer: 1024 * 1024,
      env: { ...process.env, PATH: process.env.PATH },
    });

    return NextResponse.json({ stdout, stderr, exitCode: 0 });
  } catch (err: unknown) {
    const error = err as { stdout?: string; stderr?: string; code?: number; message?: string };
    return NextResponse.json({
      stdout: error.stdout || '',
      stderr: error.stderr || error.message || String(err),
      exitCode: error.code ?? 1,
    });
  }
}
