#!/usr/bin/env node

// Load .env file from project root (Node >= 20.12 built-in, no dotenv needed).
// Silent no-op if the file doesn't exist.
try { process.loadEnvFile(); } catch { /* .env not found — that's fine */ }

import './suppressNodeWarnings.js';
import { realpathSync } from 'node:fs';
import { resolve } from 'node:path';
import { fileURLToPath } from 'node:url';
import { Command } from 'commander';
import { registerStartCommand } from './start.js';
import { registerSendCommand } from './send.js';
import { registerSessionsCommand } from './sessions.js';
import { registerDoctorCommand } from './doctor.js';
import { registerConfigCommand } from './config-cmd.js';
import { registerTuiCommand } from './tui.js';
import { registerCompletionCommand } from './completion.js';
import { registerSetupCommand } from './setup.js';
import { registerOnboardCommand } from './onboard.js';
import { registerGmailAuthCommand } from './gmail-auth.js';
import { registerGcalAuthCommand } from './gcal-auth.js';
import { registerGdocsAuthCommand } from './gdocs-auth.js';
import { registerGdriveAuthCommand } from './gdrive-auth.js';
import { registerGtasksAuthCommand } from './gtasks-auth.js';
import { registerGoogleAuthCommand } from './google-auth.js';
import { registerOpenaiAuthCommand } from './openai-auth.js';
import { registerOpenaiKeyCommand } from './openai-key.js';
import { registerZaiAuthCommand } from './zai-auth.js';
import { registerAnthropicAuthCommand } from './anthropic-auth.js';
import { registerGeminiAuthCommand } from './gemini-auth.js';
import { registerSkillsCommand } from './skills.js';
import { registerBackupCommand } from './backup.js';
import { registerCompanionCommand } from './companion.js';

export function createProgram(): Command {
  const program = new Command();

  program
    .name('flynn')
    .description('Flynn — self-hosted personal AI agent')
    .version('0.1.0');

  registerStartCommand(program);
  registerTuiCommand(program);
  registerSendCommand(program);
  registerSessionsCommand(program);
  registerDoctorCommand(program);
  registerConfigCommand(program);
  registerCompletionCommand(program);
  registerSetupCommand(program);
  registerOnboardCommand(program);
  registerGmailAuthCommand(program);
  registerGcalAuthCommand(program);
  registerGdocsAuthCommand(program);
  registerGdriveAuthCommand(program);
  registerGtasksAuthCommand(program);
  registerGoogleAuthCommand(program);
  registerOpenaiAuthCommand(program);
  registerOpenaiKeyCommand(program);
  registerZaiAuthCommand(program);
  registerAnthropicAuthCommand(program);
  registerGeminiAuthCommand(program);
  registerSkillsCommand(program);
  registerBackupCommand(program);
  registerCompanionCommand(program);

  return program;
}

// Only run when executed directly (not imported in tests).
// Resolve symlinks so installed shims (e.g. ~/.local/bin/flynn) still execute the CLI.
function isDirectRun(): boolean {
  if (!process.argv[1]) {
    return false;
  }

  try {
    const currentFile = realpathSync(fileURLToPath(import.meta.url));
    const invokedFile = realpathSync(resolve(process.argv[1]));
    return currentFile === invokedFile;
  } catch {
    return false;
  }
}

export function normalizeAliasFlags(argv: string[]): string[] {
  const aliasMap: Record<string, string> = {
    '--anthropic-auth': 'anthropic-auth',
    '--gemini-auth': 'gemini-auth',
    '--zai-auth': 'zai-auth',
    '--openai-auth': 'openai-auth',
    '--openai-key': 'openai-key',
  };

  for (const [flag, command] of Object.entries(aliasMap)) {
    if (argv.includes(flag)) {
      const filtered = argv.filter((arg) => arg !== flag);
      return [filtered[0] ?? 'node', filtered[1] ?? 'flynn', command, ...filtered.slice(2)];
    }
  }

  return argv;
}

if (isDirectRun()) {
  const program = createProgram();
  const normalizedArgv = normalizeAliasFlags(process.argv);
  const argv = normalizedArgv.length <= 2
    ? [...normalizedArgv, 'tui']
    : normalizedArgv;
  program.parse(argv);
}
