/**
 * R2 — route-level HTTP tests for POST /api/jobs autopilot semantics.
 *
 * Mirrors the handler in src/server/index.ts (resolveJobAutopilot +
 * autopilotDefault), exercised over a real listening server (same pattern as
 * global-stats-admin.test.ts — no supertest). Production wiring is also
 * pinned via a source-level contract so this mini-app cannot drift.
 */
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
import express from 'express';
import fs from 'node:fs';
import path from 'node:path';
import type { AddressInfo } from 'node:net';
import { resolveJobAutopilot } from '../src/server/jobAutopilot';

/** Minimal POST /api/jobs surface that shares the production resolve path. */
function createJobsAutopilotApp(opts: {
  getAutopilotDefault: () => boolean;
  onCreate: (prompt: string, autopilot: boolean) => void;
}) {
  const app = express();
  app.use(express.json());
  app.post('/api/jobs', (req, res) => {
    const prompt = String(req.body?.prompt ?? '').trim();
    if (!prompt) {
      res.status(400).json({ error: 'prompt is required' });
      return;
    }
    // Keep in lockstep with src/server/index.ts:
    //   resolveJobAutopilot(req.body?.autopilot, getConfig().autopilotDefault)
    const autopilot = resolveJobAutopilot(req.body?.autopilot, opts.getAutopilotDefault());
    opts.onCreate(prompt, autopilot);
    res.status(201).json({ prompt, autopilot });
  });
  return app;
}

describe('R2 POST /api/jobs autopilot (route-level HTTP)', () => {
  let server: ReturnType<express.Express['listen']>;
  let base: string;
  let lastCreate: { prompt: string; autopilot: boolean } | null;
  let autopilotDefault: boolean;

  beforeEach(async () => {
    lastCreate = null;
    autopilotDefault = true;
    const app = createJobsAutopilotApp({
      getAutopilotDefault: () => autopilotDefault,
      onCreate: (prompt, autopilot) => {
        lastCreate = { prompt, autopilot };
      },
    });
    await new Promise<void>(resolve => {
      server = app.listen(0, () => resolve());
    });
    const port = (server.address() as AddressInfo).port;
    base = `http://127.0.0.1:${port}`;
  });

  afterEach(async () => {
    await new Promise<void>(resolve => server.close(() => resolve()));
  });

  it('production index.ts wires resolveJobAutopilot + autopilotDefault', () => {
    const src = fs.readFileSync(path.resolve('src/server/index.ts'), 'utf8');
    expect(src).toContain("app.post('/api/jobs'");
    expect(src).toContain('resolveJobAutopilot(req.body?.autopilot, getConfig().autopilotDefault)');
  });

  it('omitted autopilot → config default (true → autopilot)', async () => {
    autopilotDefault = true;
    const r = await fetch(`${base}/api/jobs`, {
      method: 'POST',
      headers: { 'content-type': 'application/json' },
      body: JSON.stringify({ prompt: 'build a todo app' }),
    });
    expect(r.status).toBe(201);
    const j = await r.json() as { autopilot: boolean };
    expect(j.autopilot).toBe(true);
    expect(lastCreate?.autopilot).toBe(true);
  });

  it('omitted autopilot → config default (false → supervised)', async () => {
    autopilotDefault = false;
    const r = await fetch(`${base}/api/jobs`, {
      method: 'POST',
      headers: { 'content-type': 'application/json' },
      body: JSON.stringify({ prompt: 'build a todo app' }),
    });
    expect(r.status).toBe(201);
    const j = await r.json() as { autopilot: boolean };
    expect(j.autopilot).toBe(false);
    expect(lastCreate?.autopilot).toBe(false);
  });

  it('explicit false → supervised even when default is autopilot', async () => {
    autopilotDefault = true;
    const r = await fetch(`${base}/api/jobs`, {
      method: 'POST',
      headers: { 'content-type': 'application/json' },
      body: JSON.stringify({ prompt: 'build a todo app', autopilot: false }),
    });
    expect(r.status).toBe(201);
    const j = await r.json() as { autopilot: boolean };
    expect(j.autopilot).toBe(false);
    expect(lastCreate?.autopilot).toBe(false);
  });

  it('explicit true → autopilot even when default is supervised', async () => {
    autopilotDefault = false;
    const r = await fetch(`${base}/api/jobs`, {
      method: 'POST',
      headers: { 'content-type': 'application/json' },
      body: JSON.stringify({ prompt: 'build a todo app', autopilot: true }),
    });
    expect(r.status).toBe(201);
    const j = await r.json() as { autopilot: boolean };
    expect(j.autopilot).toBe(true);
    expect(lastCreate?.autopilot).toBe(true);
  });
});
