import { Command } from 'commander';
import { resolve, join } from 'node:path';
import { readdirSync, readFileSync, existsSync } from 'node:fs';
import { RegistryClient, readCredentials } from '@expxagents/registry-client';
import { load as loadYaml } from 'js-yaml';
export function scanInstalledSquads(squadsDir) {
    const installed = [];
    if (!existsSync(squadsDir))
        return installed;
    for (const entry of readdirSync(squadsDir, { withFileTypes: true })) {
        if (!entry.isDirectory() || !entry.name.startsWith('@'))
            continue;
        const scope = entry.name.slice(1); // remove @
        const scopeDir = join(squadsDir, entry.name);
        for (const squadEntry of readdirSync(scopeDir, { withFileTypes: true })) {
            if (!squadEntry.isDirectory())
                continue;
            // Tarball may extract as @scope/name/squad.yaml or @scope/name/name/squad.yaml
            const directPath = join(scopeDir, squadEntry.name, 'squad.yaml');
            const nestedPath = join(scopeDir, squadEntry.name, squadEntry.name, 'squad.yaml');
            const yamlPath = existsSync(directPath) ? directPath : existsSync(nestedPath) ? nestedPath : null;
            if (!yamlPath)
                continue;
            try {
                const raw = readFileSync(yamlPath, 'utf-8');
                const parsed = loadYaml(raw);
                const version = parsed?.squad?.version ?? parsed?.version;
                if (version) {
                    installed.push({
                        fullName: `@${scope}/${squadEntry.name}`,
                        currentVersion: String(version),
                    });
                }
            }
            catch {
                // Skip squads with invalid yaml
            }
        }
    }
    return installed;
}
export async function checkOutdated(client, squads) {
    const outdated = [];
    for (const squad of squads) {
        try {
            const meta = await client.getSquad(squad.fullName);
            if (meta.latestVersion && meta.latestVersion !== squad.currentVersion) {
                outdated.push({
                    fullName: squad.fullName,
                    current: squad.currentVersion,
                    latest: meta.latestVersion,
                });
            }
        }
        catch {
            // Squad not found on registry — skip (local-only squad)
        }
    }
    return outdated;
}
export const outdatedCommand = new Command('outdated')
    .description('Check installed squads for available updates')
    .option('--dir <dir>', 'Squads directory', './squads')
    .action(async (options) => {
    const squadsDir = resolve(options.dir);
    const installed = scanInstalledSquads(squadsDir);
    if (installed.length === 0) {
        console.log('No registry squads installed.');
        return;
    }
    const creds = readCredentials();
    const client = new RegistryClient({
        registryUrl: creds?.registryUrl || 'https://expxagents-marketplace-production.up.railway.app',
        apiKey: creds?.apiKey,
    });
    console.log(`Checking ${installed.length} squad(s)...\n`);
    const outdated = await checkOutdated(client, installed);
    if (outdated.length === 0) {
        console.log('All squads are up to date.');
        return;
    }
    console.log('Updates available:\n');
    for (const o of outdated) {
        console.log(`  ${o.fullName}  ${o.current} \u2192 ${o.latest}`);
    }
    console.log(`\nRun \`expxagents update\` to update all.`);
});
