import { describe, it, expect } from 'vitest';
import { createProgram } from '../../src/index.js';

/**
 * End-to-end tests that verify CLI command registration and help output
 * without requiring a running daemon.
 */
describe('CLI command registration (e2e)', () => {
  it('program has all expected commands', () => {
    const program = createProgram();
    const commandNames = program.commands.map((c) => c.name());

    expect(commandNames).toContain('config');
    expect(commandNames).toContain('status');
    expect(commandNames).toContain('login');
    expect(commandNames).toContain('logout');
    expect(commandNames).toContain('get');
    expect(commandNames).toContain('describe');
    expect(commandNames).toContain('delete');
    expect(commandNames).toContain('logs');
    expect(commandNames).toContain('apply');
    expect(commandNames).toContain('create');
    expect(commandNames).toContain('edit');
    expect(commandNames).toContain('backup');
  });

  it('old project and claude top-level commands are removed', () => {
    const program = createProgram();
    const commandNames = program.commands.map((c) => c.name());
    expect(commandNames).not.toContain('claude');
    expect(commandNames).not.toContain('project');
    expect(commandNames).not.toContain('instance');
  });

  it('config command has claude-generate and impersonate subcommands', () => {
    const program = createProgram();
    const config = program.commands.find((c) => c.name() === 'config');
    expect(config).toBeDefined();

    const subcommands = config!.commands.map((c) => c.name());
    expect(subcommands).toContain('claude-generate');
    expect(subcommands).toContain('impersonate');
    expect(subcommands).toContain('view');
    expect(subcommands).toContain('set');
    expect(subcommands).toContain('path');
    expect(subcommands).toContain('reset');
  });

  it('create command has user, group, rbac, prompt, promptrequest subcommands', () => {
    const program = createProgram();
    const create = program.commands.find((c) => c.name() === 'create');
    expect(create).toBeDefined();

    const subcommands = create!.commands.map((c) => c.name());
    expect(subcommands).toContain('server');
    expect(subcommands).toContain('secret');
    expect(subcommands).toContain('project');
    expect(subcommands).toContain('user');
    expect(subcommands).toContain('group');
    expect(subcommands).toContain('rbac');
    expect(subcommands).toContain('prompt');
    expect(subcommands).toContain('promptrequest');
  });

  it('get command accepts --project option', () => {
    const program = createProgram();
    const get = program.commands.find((c) => c.name() === 'get');
    expect(get).toBeDefined();

    const projectOpt = get!.options.find((o) => o.long === '--project');
    expect(projectOpt).toBeDefined();
    expect(projectOpt!.description).toContain('project');
  });

  it('program-level --project option is defined', () => {
    const program = createProgram();
    const projectOpt = program.options.find((o) => o.long === '--project');
    expect(projectOpt).toBeDefined();
  });

  it('displays version', () => {
    const program = createProgram();
    expect(program.version()).toBeDefined();
    expect(program.version()).toMatch(/^\d+\.\d+\.\d+$/);
  });

  it('displays help without error', () => {
    const program = createProgram();
    const helpText = program.helpInformation();
    expect(helpText).toContain('mcpctl');
    expect(helpText).toContain('Manage MCP servers');
  });
});
