// tools/import-spec-handler.ts — Handles import_spec and bulk_import tools (SPEC-285)
import { readFile } from 'node:fs/promises';
import { handleCreateSpec } from './create-spec.js';
import { parseMarkdown } from '../engine/importers/markdown-importer.js';
import { parseCsv } from '../engine/importers/csv-importer.js';
import { compactResult, compactError, formatKeyValue } from './output-formatter.js';
// ---------------------------------------------------------------------------
// Internal helpers
// ---------------------------------------------------------------------------
/** Load content from filePath or inline content string */
async function resolveContent(filePath, content) {
    if (content) {
        return content;
    }
    if (filePath) {
        return readFile(filePath, 'utf-8');
    }
    throw new Error('Either filePath or content must be provided');
}
/** Build a description string from ImportedSpec for create_spec */
function buildDescription(spec, source, externalId) {
    const parts = [];
    if (spec.description) {
        parts.push(spec.description);
        parts.push('');
    }
    if (spec.criteria.length > 0) {
        parts.push('## Acceptance Criteria');
        spec.criteria.forEach((c) => parts.push(`- [ ] ${c}`));
        parts.push('');
    }
    if (externalId) {
        parts.push(`_Imported from ${source}: ${externalId}_`);
    }
    else {
        parts.push(`_Imported from ${source}_`);
    }
    return parts.join('\n').trim();
}
/** Create a single spec from an ImportedSpec object */
async function createFromImported(imported, source, projectPath, overwrite) {
    const description = buildDescription(imported, source, imported.externalId);
    // Build tags: original tags + source tag
    const tags = [...imported.tags, `source:${source}`];
    if (imported.externalId) {
        tags.push(`externalId:${imported.externalId}`);
    }
    try {
        const result = await handleCreateSpec({
            title: imported.title,
            description,
            projectPath,
            tags,
            type: 'feature',
            scope: 'feature',
            target: 'fullstack',
        });
        if (result.isError) {
            const text = result.content[0]?.type === 'text' ? result.content[0].text : 'Unknown error';
            // Detect duplicate title
            if (text.includes('already exists') || text.includes('duplicate')) {
                if (!overwrite) {
                    return {
                        success: false,
                        title: imported.title,
                        externalId: imported.externalId,
                        warning: `Spec with title "${imported.title}" already exists. Use overwrite:true to replace it.`,
                    };
                }
                // overwrite=true: proceed anyway (create still fails; caller should handle)
            }
            return {
                success: false,
                title: imported.title,
                externalId: imported.externalId,
                error: text,
            };
        }
        // Extract specId from result JSON
        const text = result.content[0]?.type === 'text' ? result.content[0].text : '';
        let specId;
        try {
            const parsed = JSON.parse(text);
            specId = typeof parsed.specId === 'string' ? parsed.specId : undefined;
        }
        catch {
            // text may not be JSON — ignore
        }
        return {
            success: true,
            specId,
            title: imported.title,
            externalId: imported.externalId,
        };
    }
    catch (err) {
        return {
            success: false,
            title: imported.title,
            externalId: imported.externalId,
            error: err instanceof Error ? err.message : String(err),
        };
    }
}
// ---------------------------------------------------------------------------
// Public handlers
// ---------------------------------------------------------------------------
/**
 * Handle import_spec: import a single spec from markdown, jira, or linear.
 */
export async function handleImportSpec(params) {
    const { source, filePath, content, projectPath, overwrite = false } = params;
    try {
        const rawContent = await resolveContent(filePath, content);
        let imported;
        switch (source) {
            case 'markdown':
                imported = parseMarkdown(rawContent);
                break;
            case 'csv': {
                const rows = parseCsv(rawContent);
                if (rows.length === 0) {
                    return compactError('❌ CSV has no data rows');
                }
                // Single import: use first row only
                const first = rows[0];
                if (!first) {
                    return compactError('❌ CSV row is empty');
                }
                imported = first;
                break;
            }
            default:
                return compactError(`❌ Unknown source: ${String(source)}. Valid values: markdown, csv`);
        }
        const result = await createFromImported(imported, source, projectPath, overwrite);
        const msg = result.success
            ? `Imported "${result.title}"${result.specId ? ` as ${result.specId}` : ''}`
            : `Failed to import "${result.title}": ${result.error ?? result.warning ?? 'unknown error'}`;
        return compactResult(formatKeyValue({ ...result }, 'Import Result') + `\n\n${msg}`);
    }
    catch (err) {
        return compactError(`❌ Import failed: ${err instanceof Error ? err.message : String(err)}`);
    }
}
/**
 * Handle bulk_import: import multiple specs from CSV or multiple JSON items.
 */
export async function handleBulkImport(params) {
    const { source, filePath, content, projectPath, overwrite = false } = params;
    try {
        const rawContent = await resolveContent(filePath, content);
        let specs;
        if (source === 'csv') {
            specs = parseCsv(rawContent);
        }
        else {
            // For non-CSV sources, expect a JSON array of issues
            let parsed;
            try {
                parsed = JSON.parse(rawContent);
            }
            catch {
                throw new Error(`bulk_import with source "${source}" expects a JSON array of issues`);
            }
            if (!Array.isArray(parsed)) {
                throw new Error(`bulk_import: content must be a JSON array, got ${typeof parsed}`);
            }
            specs = parsed.map((item) => parseMarkdown(typeof item === 'string' ? item : JSON.stringify(item)));
        }
        if (specs.length === 0) {
            return compactResult('No specs to import (empty input).');
        }
        const results = [];
        for (const spec of specs) {
            const r = await createFromImported(spec, source, projectPath, overwrite);
            results.push(r);
        }
        const succeeded = results.filter((r) => r.success).length;
        const failed = results.length - succeeded;
        const bulkResult = {
            total: results.length,
            succeeded,
            failed,
            results,
        };
        return compactResult(formatKeyValue({ total: bulkResult.total, succeeded: bulkResult.succeeded, failed: bulkResult.failed }, 'Bulk Import') +
            (bulkResult.results.length > 0
                ? '\n\n' +
                    bulkResult.results.map((r) => `- ${r.success ? '✓' : '✗'} ${r.title}`).join('\n')
                : ''));
    }
    catch (err) {
        return compactError(`❌ Bulk import failed: ${err instanceof Error ? err.message : String(err)}`);
    }
}
//# sourceMappingURL=import-spec-handler.js.map