/**
 * Adapter Loader
 *
 * Loads adapters from registry, detects tools, and provides API for init command.
 * Enables SpecWeave to work with ANY AI coding tool.
 */
import * as fs from '../utils/fs-native.js';
import * as path from 'path';
import * as YAML from 'yaml';
import { AntigravityAdapter } from './antigravity/adapter.js';
import { CursorAdapter } from './cursor/adapter.js';
import { GeminiAdapter } from './gemini/adapter.js';
import { CodexAdapter } from './codex/adapter.js';
import { GenericAdapter } from './generic/adapter.js';
import { CopilotAdapter } from './copilot/adapter.js';
import { WindsurfAdapter } from './windsurf/adapter.js';
import { ContinueAdapter } from './continue/adapter.js';
import { ClineAdapter } from './cline/adapter.js';
import { ZedAdapter } from './zed/adapter.js';
import { AmazonQAdapter } from './amazonq/adapter.js';
import { JetBrainsAdapter } from './jetbrains/adapter.js';
import { AiderAdapter } from './aider/adapter.js';
import { TabnineAdapter } from './tabnine/adapter.js';
import { KimiAdapter } from './kimi/adapter.js';
import { TraeAdapter } from './trae/adapter.js';
import { OpenCodeAdapter } from './opencode/adapter.js';
import { getDirname } from '../utils/esm-helpers.js';
import { detectClaudeCli } from '../utils/claude-cli-detector.js';
const __dirname = getDirname(import.meta.url);
/**
 * Adapter Loader - Main API for working with adapters
 */
export class AdapterLoader {
    constructor() {
        this.adapters = new Map();
        this.registry = null;
        this.initializeAdapters();
    }
    /**
     * Initialize all adapters
     *
     * NOTE: Claude Code is NOT an adapter - it's the native/default experience!
     * Adapters only exist for tools that need to APPROXIMATE Claude's native capabilities.
     */
    initializeAdapters() {
        // Note: No ClaudeAdapter - Claude is the baseline, not an adaptation!
        this.adapters.set('antigravity', new AntigravityAdapter());
        this.adapters.set('codex', new CodexAdapter());
        this.adapters.set('opencode', new OpenCodeAdapter());
        this.adapters.set('copilot', new CopilotAdapter());
        this.adapters.set('cursor', new CursorAdapter());
        this.adapters.set('windsurf', new WindsurfAdapter());
        this.adapters.set('cline', new ClineAdapter());
        this.adapters.set('gemini', new GeminiAdapter());
        this.adapters.set('amazonq', new AmazonQAdapter());
        this.adapters.set('jetbrains', new JetBrainsAdapter());
        this.adapters.set('continue', new ContinueAdapter());
        this.adapters.set('aider', new AiderAdapter());
        this.adapters.set('trae', new TraeAdapter());
        this.adapters.set('zed', new ZedAdapter());
        this.adapters.set('tabnine', new TabnineAdapter());
        this.adapters.set('kimi', new KimiAdapter());
        this.adapters.set('generic', new GenericAdapter());
    }
    /**
     * Load registry.yaml
     */
    async loadRegistry() {
        if (this.registry) {
            return this.registry;
        }
        // Try dist first, then fall back to src (for development)
        let registryPath = path.join(__dirname, 'registry.yaml');
        if (!await fs.pathExists(registryPath)) {
            registryPath = path.join(__dirname, '../../src/adapters/registry.yaml');
        }
        const content = await fs.readFile(registryPath, 'utf-8');
        this.registry = YAML.parse(content);
        return this.registry;
    }
    /**
     * Get all available adapters
     */
    getAllAdapters() {
        return Array.from(this.adapters.values());
    }
    /**
     * Get adapter by name
     */
    getAdapter(name) {
        return this.adapters.get(name);
    }
    /**
     * Auto-detect which tool is being used
     *
     * Detection priority (Claude-first! SpecWeave is built for Claude):
     * 1. Claude Code (FIRST! If claude CLI is available, use it - active indicator)
     * 2. Cursor (only if Claude unavailable AND cursor indicators exist)
     * 3. Gemini CLI (only if Claude unavailable)
     * 4. Codex (only if Claude unavailable)
     * 5. Generic (only if explicitly requested via --adapter generic)
     *
     * Rationale: Claude CLI being available is an ACTIVE indicator (user installed it).
     * `.cursor/` directory is a PASSIVE indicator (may exist from old usage).
     * If user has both, they almost certainly want Claude (since SpecWeave is native to it).
     *
     * @returns Promise<string> Detected tool name (not adapter - Claude has no adapter!)
     */
    async detectTool() {
        console.log('🔍 Detecting AI coding tool...\n');
        // ✅ CLAUDE FIRST! SpecWeave is built for Claude Code.
        // Claude CLI being available = user wants Claude (active indicator)
        const claudeStatus = detectClaudeCli();
        if (claudeStatus.available) {
            // Claude CLI is fully functional - this is the native experience!
            console.log(`✅ Detected: Claude Code (native plugin system, full automation)`);
            console.log(`   Found 'claude' command in PATH`);
            console.log('');
            return 'claude';
        }
        // Claude not available - check other tools (passive indicators)
        const detectionOrder = ['antigravity', 'codex', 'opencode', 'copilot', 'cursor', 'windsurf', 'cline', 'gemini', 'amazonq', 'jetbrains', 'continue', 'aider', 'trae', 'zed', 'tabnine', 'kimi'];
        for (const adapterName of detectionOrder) {
            const adapter = this.adapters.get(adapterName);
            if (!adapter)
                continue;
            const detected = await adapter.detect();
            if (detected) {
                console.log(`✅ Detected: ${adapter.name} (${adapter.automationLevel} automation)`);
                return adapterName;
            }
        }
        // No tool detected at all
        if (claudeStatus.commandExists) {
            // Claude command exists but plugin commands don't work
            console.log(`⚠️  Claude command found but not fully functional`);
            console.log(`   Issue: ${claudeStatus.error}`);
            console.log(`   Will still use Claude (may need manual plugin install)`);
            console.log('');
        }
        else {
            // Claude CLI NOT installed - recommend it
            console.log(`ℹ️  No specific tool detected - recommending Claude Code (best experience)`);
            console.log(`   💡 Use --adapter flag to specify a different tool if needed`);
            console.log('');
        }
        return 'claude';
    }
    /**
     * Check requirements for a specific adapter
     */
    async checkRequirements(adapterName) {
        const adapter = this.adapters.get(adapterName);
        if (!adapter) {
            throw new Error(`Adapter not found: ${adapterName}`);
        }
        const result = await adapter.checkRequirements();
        if (!result.met) {
            console.error('\n❌ Requirements not met:\n');
            result.missing.forEach(req => console.error(`  - ${req}`));
            throw new Error('System requirements not met');
        }
        if (result.warnings.length > 0) {
            console.warn('\n⚠️  Warnings:\n');
            result.warnings.forEach(warning => console.warn(`  - ${warning}`));
        }
    }
    /**
     * List all available adapters with details
     */
    async listAdapters() {
        const registry = await this.loadRegistry();
        console.log('\n📋 SpecWeave Tool Support:\n');
        console.log('━'.repeat(70));
        console.log('');
        // Show Claude first (baseline, not an adapter)
        const claudeInfo = registry.adapters.find(a => a.name === 'claude');
        if (claudeInfo) {
            console.log(`🚀 CLAUDE CODE (Baseline - No Adapter Needed)`);
            console.log(`   ${claudeInfo.description}`);
            console.log(`   Native: skills, agents, hooks, slash commands | Market: ${claudeInfo.market_share}`);
            console.log('');
        }
        console.log('📦 Adapters (For Other Tools):\n');
        // Show other adapters
        for (const adapterInfo of registry.adapters) {
            if (adapterInfo.name === 'claude')
                continue; // Skip Claude, already shown
            const adapter = this.adapters.get(adapterInfo.name);
            if (!adapter)
                continue;
            console.log(`${this.getAutomationIcon(adapter.automationLevel)} ${adapter.name.toUpperCase()}`);
            console.log(`   ${adapter.description}`);
            console.log(`   Automation: ${adapter.automationLevel} | Market: ${adapterInfo.market_share}`);
            console.log('');
        }
        console.log('━'.repeat(70));
        console.log('\nTotal Market Coverage: 100%');
        console.log('SpecWeave works with ANY AI coding tool!');
        console.log('\n💡 Claude Code = Native experience (no adapter)');
        console.log('   Other tools = Adapters approximate Claude\'s capabilities\n');
    }
    /**
     * Get icon for automation level
     */
    getAutomationIcon(level) {
        switch (level) {
            case 'full': return '🚀';
            case 'semi': return '⚡';
            case 'basic': return '📝';
            case 'manual': return '📖';
            default: return '❓';
        }
    }
    /**
     * Get recommended adapter based on detection and user preference
     *
     * Returns null if Claude is detected (native experience, no adapter needed)
     */
    async getRecommendedAdapter(explicitChoice) {
        // If user explicitly chose an adapter, use it
        if (explicitChoice) {
            // 'claude' is a valid explicit choice - means "use native Claude"
            if (explicitChoice === 'claude') {
                return null; // No adapter needed for Claude
            }
            const adapter = this.adapters.get(explicitChoice);
            if (!adapter) {
                throw new Error(`Invalid adapter: ${explicitChoice}. Valid values: claude, antigravity, codex, opencode, copilot, cursor, windsurf, cline, gemini, amazonq, jetbrains, continue, aider, trae, zed, tabnine, kimi, generic`);
            }
            return adapter;
        }
        // Otherwise, auto-detect
        const detectedName = await this.detectTool();
        // Claude detected - native experience, no adapter needed
        if (detectedName === 'claude') {
            return null;
        }
        const adapter = this.adapters.get(detectedName);
        if (!adapter) {
            throw new Error(`Detected adapter not found: ${detectedName}`);
        }
        return adapter;
    }
}
//# sourceMappingURL=adapter-loader.js.map