import { describe, it, expect, beforeEach, afterEach } from 'vitest';
import { mkdtempSync, rmSync } from 'fs';
import { tmpdir } from 'os';
import { join } from 'path';
import request from 'supertest';
import { Repository } from '../db/repository.js';
import { createCoreServer } from './server.js';

/**
 * Characterization test pinning the MCP + SSH subsystem wiring inside
 * createCoreServer, so the extraction of those two blocks into dedicated
 * setup helpers stays behavior-preserving. No test booted createCoreServer
 * before this; the only runtime caller is worker-bootstrap (production).
 *
 * - MCP routes mount only when MCP_ENCRYPTION_KEY is configured (gate).
 * - SSH is disabled by default config → sshConsole is null (gate).
 * - The whole server still boots and serves a basic route either way.
 */
describe('createCoreServer subsystem wiring', () => {
  let tempDir: string;
  let repo: Repository;
  const KEY = 'a'.repeat(64); // 32-byte hex

  beforeEach(() => {
    tempDir = mkdtempSync(join(tmpdir(), 'core-subsys-'));
    repo = new Repository(join(tempDir, 'db.sqlite'));
  });

  afterEach(() => {
    delete process.env.MCP_ENCRYPTION_KEY;
    repo.close();
    rmSync(tempDir, { recursive: true, force: true });
  });

  it('mounts MCP routers when MCP_ENCRYPTION_KEY is configured', async () => {
    process.env.MCP_ENCRYPTION_KEY = KEY;
    const { app, sshConsole, authActive } = createCoreServer({ repo, worktreeDir: join(tempDir, 'wt') });
    expect(typeof authActive).toBe('boolean');
    // SSH is disabled by default config → the subsystem returns null.
    expect(sshConsole).toBeNull();
    // MCP admin router is mounted (not a 404 from the express fallthrough).
    const res = await request(app).get('/api/mcp/servers');
    expect(res.status).not.toBe(404);
  });

  it('does NOT mount MCP routers when the key is absent', async () => {
    delete process.env.MCP_ENCRYPTION_KEY;
    const { app } = createCoreServer({ repo, worktreeDir: join(tempDir, 'wt') });
    const res = await request(app).get('/api/mcp/servers');
    // No key → MCP block skipped → unmatched route → 404 fallthrough handler.
    expect(res.status).toBe(404);
  });

  it('boots and serves /api/local/tasks regardless of MCP key', async () => {
    const { app } = createCoreServer({ repo, worktreeDir: join(tempDir, 'wt') });
    const res = await request(app).get('/api/local/tasks');
    expect(res.status).toBe(200);
    expect(Array.isArray(res.body.tasks)).toBe(true);
  });
});
