import path from 'path';
import { FileSystemUtils } from '../utils/file-system.js';
import { OPENSPEC_DIR_NAME } from './config.js';
import { ToolRegistry } from './configurators/registry.js';
import { SlashCommandRegistry } from './configurators/slash/registry.js';
import { agentsTemplate } from './templates/agents-template.js';
export class UpdateCommand {
    async execute(projectPath) {
        const resolvedProjectPath = path.resolve(projectPath);
        const openspecDirName = OPENSPEC_DIR_NAME;
        const openspecPath = path.join(resolvedProjectPath, openspecDirName);
        // 1. Check openspec directory exists
        if (!await FileSystemUtils.directoryExists(openspecPath)) {
            throw new Error(`No OpenSpec directory found. Run 'openspec init' first.`);
        }
        // 2. Update AGENTS.md (full replacement)
        const agentsPath = path.join(openspecPath, 'AGENTS.md');
        await FileSystemUtils.writeFile(agentsPath, agentsTemplate);
        // 3. Update existing AI tool configuration files only
        const configurators = ToolRegistry.getAll();
        const slashConfigurators = SlashCommandRegistry.getAll();
        const updatedFiles = [];
        const createdFiles = [];
        const failedFiles = [];
        const updatedSlashFiles = [];
        const failedSlashTools = [];
        for (const configurator of configurators) {
            const configFilePath = path.join(resolvedProjectPath, configurator.configFileName);
            const fileExists = await FileSystemUtils.fileExists(configFilePath);
            const shouldConfigure = fileExists || configurator.configFileName === 'AGENTS.md';
            if (!shouldConfigure) {
                continue;
            }
            try {
                if (fileExists && !await FileSystemUtils.canWriteFile(configFilePath)) {
                    throw new Error(`Insufficient permissions to modify ${configurator.configFileName}`);
                }
                await configurator.configure(resolvedProjectPath, openspecPath);
                updatedFiles.push(configurator.configFileName);
                if (!fileExists) {
                    createdFiles.push(configurator.configFileName);
                }
            }
            catch (error) {
                failedFiles.push(configurator.configFileName);
                console.error(`Failed to update ${configurator.configFileName}: ${error instanceof Error ? error.message : String(error)}`);
            }
        }
        for (const slashConfigurator of slashConfigurators) {
            if (!slashConfigurator.isAvailable) {
                continue;
            }
            try {
                const updated = await slashConfigurator.updateExisting(resolvedProjectPath, openspecPath);
                updatedSlashFiles.push(...updated);
            }
            catch (error) {
                failedSlashTools.push(slashConfigurator.toolId);
                console.error(`Failed to update slash commands for ${slashConfigurator.toolId}: ${error instanceof Error ? error.message : String(error)}`);
            }
        }
        const summaryParts = [];
        const instructionFiles = ['openspec/AGENTS.md'];
        if (updatedFiles.includes('AGENTS.md')) {
            instructionFiles.push(createdFiles.includes('AGENTS.md') ? 'AGENTS.md (created)' : 'AGENTS.md');
        }
        summaryParts.push(`Updated OpenSpec instructions (${instructionFiles.join(', ')})`);
        const aiToolFiles = updatedFiles.filter((file) => file !== 'AGENTS.md');
        if (aiToolFiles.length > 0) {
            summaryParts.push(`Updated AI tool files: ${aiToolFiles.join(', ')}`);
        }
        if (updatedSlashFiles.length > 0) {
            // Normalize to forward slashes for cross-platform log consistency
            const normalized = updatedSlashFiles.map((p) => FileSystemUtils.toPosixPath(p));
            summaryParts.push(`Updated slash commands: ${normalized.join(', ')}`);
        }
        const failedItems = [
            ...failedFiles,
            ...failedSlashTools.map((toolId) => `slash command refresh (${toolId})`),
        ];
        if (failedItems.length > 0) {
            summaryParts.push(`Failed to update: ${failedItems.join(', ')}`);
        }
        console.log(summaryParts.join(' | '));
        // No additional notes
    }
}
//# sourceMappingURL=update.js.map