// tools/registry/install.ts — AC-6: Install a spec from the registry to local project
import { readdir, writeFile, mkdir } from 'node:fs/promises';
import { join } from 'node:path';
import { generateSpecId, slugify } from '../create-spec-helpers.js';
/** Scan existing specs directory to collect current spec IDs. */
async function collectExistingSpecIds(specsDir) {
    try {
        const entries = await readdir(specsDir, { withFileTypes: true });
        return entries
            .filter((e) => e.isDirectory() && e.name.startsWith('SPEC-'))
            .map((e) => {
            const match = /^(SPEC-\d+)/.exec(e.name);
            /* v8 ignore next -- regex always matches SPEC- prefix from filter */
            return { id: match?.[1] ?? '' };
        })
            .filter((s) => s.id !== '');
        /* v8 ignore start -- directory may not exist */
    }
    catch {
        return [];
    }
    /* v8 ignore stop */
}
/** Generate a clean progress.md for the installed spec. */
function generateProgressMd(specId, source, version) {
    const now = new Date().toISOString();
    return [
        `# ${specId} — Progress`,
        '',
        `> Installed from registry: ${source}@${version}`,
        `> Installed at: ${now}`,
        '',
        '## Status: pendiente',
        '',
        '## Acceptance Criteria',
        '',
        '- [ ] Review and adapt spec to local project',
        '- [ ] Implement according to spec',
        '- [ ] All tests passing',
        '',
    ].join('\n');
}
/**
 * Handle registry_install tool invocation.
 * Downloads a spec from the registry and installs it locally.
 */
export async function handleRegistryInstall(args) {
    try {
        const org = args.org;
        const name = args.name;
        const version = args.version ?? 'latest';
        const projectPath = args.projectPath ?? process.cwd();
        if (!org || !name) {
            return {
                content: [{ type: 'text', text: 'Missing required fields: org and name' }],
                isError: true,
            };
        }
        const { createRegistryClient, unpackSpec } = await import('../../engine/spec-registry/index.js');
        const client = createRegistryClient();
        const tarball = await client.downloadSpec(org, name, version);
        // Unpack to temp dir to read files
        const tmpDir = join(projectPath, '.planu-tmp-install');
        await mkdir(tmpDir, { recursive: true });
        await unpackSpec(tarball, tmpDir);
        const { readdir: rd, readFile: rf } = await import('node:fs/promises');
        const tmpFiles = await rd(tmpDir);
        const pkg = { files: {} };
        for (const f of tmpFiles) {
            pkg.files[f] = await rf(join(tmpDir, f), 'utf-8');
        }
        // Cleanup temp dir
        const { rm } = await import('node:fs/promises');
        await rm(tmpDir, { recursive: true, force: true });
        // Determine next spec ID
        const specsDir = join(projectPath, 'planu', 'specs');
        const existingSpecs = await collectExistingSpecIds(specsDir);
        const specId = generateSpecId(existingSpecs);
        const slug = slugify(name);
        const specDir = join(specsDir, `${specId}-${slug}`);
        // Create spec directory
        await mkdir(specDir, { recursive: true });
        // Write downloaded files, injecting registry source into spec.md frontmatter
        for (const [filePath, content] of Object.entries(pkg.files)) {
            let finalContent = content;
            if (filePath === 'spec.md') {
                finalContent = injectRegistrySource(content, org, name, version);
            }
            await writeFile(join(specDir, filePath), finalContent, 'utf-8');
        }
        // Generate local progress.md
        const source = `${org}/${name}`;
        await writeFile(join(specDir, 'progress.md'), generateProgressMd(specId, source, version), 'utf-8');
        // Attempt stack detection and spec adaptation (non-blocking on failure)
        let adapted = false;
        let adaptationsCount = 0;
        try {
            const { detectStack, adaptSpec } = await import('../../engine/spec-registry/index.js');
            const stack = await detectStack(projectPath);
            const adaptations = await adaptSpec(specDir, stack);
            if (adaptations.length > 0) {
                adapted = true;
                adaptationsCount = adaptations.length;
            }
        }
        catch {
            // Adaptation failure should not block install
        }
        const result = {
            specId,
            slug,
            specDir,
            source,
            version,
            adapted,
            ...(adapted ? { adaptations: adaptationsCount } : {}),
        };
        return {
            content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
        };
        /* v8 ignore start -- error + helper branches */
    }
    catch (error) {
        const message = error instanceof Error ? error.message : String(error);
        return {
            content: [{ type: 'text', text: `Registry install failed: ${message}` }],
            isError: true,
        };
    }
}
/** Inject registry source metadata into spec.md frontmatter. */
function injectRegistrySource(content, org, name, version) {
    const frontmatterEnd = content.indexOf('\n---', 3);
    if (frontmatterEnd === -1) {
        return content;
    }
    const insertion = `\nregistry:\n  source: "${org}/${name}"\n  version: "${version}"`;
    return content.slice(0, frontmatterEnd) + insertion + content.slice(frontmatterEnd);
}
/* v8 ignore stop */
//# sourceMappingURL=install.js.map