/**
 * Unit tests for v0.16.0 migration orchestrator + registry.
 *
 * The full schema verification lives in E2E (Postgres). These unit tests
 * cover:
 *  - registry wiring (v0.16.0 registered + lookup works)
 *  - v0.14.0 noop stub wired (gapless version sequence)
 *  - migration metadata (version, pitch)
 *  - dry-run short-circuits both phases
 *  - required table names constant
 */

import { describe, test, expect } from 'bun:test';
import { migrations, getMigration } from '../src/commands/migrations/index.ts';
import { __testing } from '../src/commands/migrations/v0_16_0.ts';

describe('v0.16.0 migration', () => {
  test('is registered in the migrations registry', () => {
    const v0_16_0 = getMigration('0.16.0');
    expect(v0_16_0).not.toBeNull();
    expect(v0_16_0?.version).toBe('0.16.0');
  });

  test('v0.14.0 noop stub is registered (gapless sequence)', () => {
    const v0_14_0 = getMigration('0.14.0');
    expect(v0_14_0).not.toBeNull();
    expect(v0_14_0?.version).toBe('0.14.0');
  });

  test('migrations array has no version gaps through 0.16.0', () => {
    const versions = migrations.map(m => m.version);
    expect(versions).toContain('0.13.1');
    expect(versions).toContain('0.14.0');
    expect(versions).toContain('0.16.0');
    // order check — registry is semver-sorted in the source
    const v15Idx = versions.indexOf('0.16.0');
    const v14Idx = versions.indexOf('0.14.0');
    const v131Idx = versions.indexOf('0.13.1');
    expect(v131Idx).toBeLessThan(v14Idx);
    expect(v14Idx).toBeLessThan(v15Idx);
  });

  test('feature pitch has headline and description', () => {
    const m = getMigration('0.16.0');
    expect(m?.featurePitch.headline).toBeTruthy();
    expect(m?.featurePitch.description).toBeTruthy();
  });

  test('REQUIRED_TABLES lists all three subagent tables', () => {
    expect(__testing.REQUIRED_TABLES).toEqual([
      'subagent_messages',
      'subagent_tool_executions',
      'subagent_rate_leases',
    ]);
  });

  test('phaseASchema skips on dry-run', async () => {
    // v0.41.37.0 #1605: phaseASchema is now async (in-process runMigrateOnlyCore).
    const r = await __testing.phaseASchema({ dryRun: true, yes: true, noAutopilotInstall: true });
    expect(r.status).toBe('skipped');
    expect(r.detail).toBe('dry-run');
  });

  test('phaseBVerify skips on dry-run', async () => {
    const r = await __testing.phaseBVerify({ dryRun: true, yes: true, noAutopilotInstall: true });
    expect(r.status).toBe('skipped');
    expect(r.detail).toBe('dry-run');
  });

  test('orchestrator in dry-run returns complete with both phases skipped', async () => {
    const m = getMigration('0.16.0');
    const result = await m!.orchestrator({ dryRun: true, yes: true, noAutopilotInstall: true });
    expect(result.version).toBe('0.16.0');
    expect(result.phases.length).toBe(2);
    expect(result.phases.every(p => p.status === 'skipped')).toBe(true);
  });
});

describe('schema-embedded.ts contains subagent tables', () => {
  test('embedded schema references all three subagent tables', async () => {
    const { SCHEMA_SQL } = await import('../src/core/schema-embedded.ts');
    expect(SCHEMA_SQL).toContain('CREATE TABLE IF NOT EXISTS subagent_messages');
    expect(SCHEMA_SQL).toContain('CREATE TABLE IF NOT EXISTS subagent_tool_executions');
    expect(SCHEMA_SQL).toContain('CREATE TABLE IF NOT EXISTS subagent_rate_leases');
    expect(SCHEMA_SQL).toContain('idx_subagent_messages_job');
    expect(SCHEMA_SQL).toContain('idx_subagent_tools_job');
    expect(SCHEMA_SQL).toContain('idx_rate_leases_key_expires');
  });
});

describe('pglite-schema.ts contains subagent tables', () => {
  test('embedded PGLite schema references all three subagent tables', async () => {
    const { PGLITE_SCHEMA_SQL } = await import('../src/core/pglite-schema.ts');
    expect(PGLITE_SCHEMA_SQL).toContain('CREATE TABLE IF NOT EXISTS subagent_messages');
    expect(PGLITE_SCHEMA_SQL).toContain('CREATE TABLE IF NOT EXISTS subagent_tool_executions');
    expect(PGLITE_SCHEMA_SQL).toContain('CREATE TABLE IF NOT EXISTS subagent_rate_leases');
  });
});
