"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.renderGeneratedSpecFile = void 0;
const ts_morph_1 = require("ts-morph");
function renderGeneratedSpecFile(args) {
    const preamble = renderPreamble(args.sourceFile);
    if (args.testCases.length === 0) {
        // Still emit a file to make behavior predictable.
        return `${preamble}\n\n// gremlin: no ${args.strategySlug} test cases generated\n`;
    }
    const describeTitle = args.testCases[0]?.originDescribeTitle ??
        'Generated - (negative) generated';
    const describeBlock = renderDescribeBlock({
        describeTitle,
        strategySlug: args.strategySlug,
        beforeEachText: args.testCases[0]?.beforeEachText,
        afterEachText: args.testCases[0]?.afterEachText,
        tests: args.testCases.map((t) => t.renderedTestText),
    });
    return `${preamble}\n\n${describeBlock}\n`;
}
exports.renderGeneratedSpecFile = renderGeneratedSpecFile;
function renderPreamble(sourceFile) {
    const keptStatements = sourceFile.getStatements().filter((stmt) => {
        if (ts_morph_1.Node.isImportDeclaration(stmt))
            return true;
        // Drop the original test.describe(...) block(s)
        if (ts_morph_1.Node.isExpressionStatement(stmt)) {
            const expr = stmt.getExpression();
            const call = expr.asKind(ts_morph_1.SyntaxKind.CallExpression);
            if (!call)
                return true;
            const callee = call.getExpression();
            // Drop top-level test('...', ...) (rare, but possible)
            if (ts_morph_1.Node.isIdentifier(callee) && callee.getText() === 'test') {
                return false;
            }
            // Drop top-level test.describe('...', ...)
            if (ts_morph_1.Node.isPropertyAccessExpression(callee)) {
                const isTestDescribe = callee.getName() === 'describe' &&
                    ts_morph_1.Node.isIdentifier(callee.getExpression()) &&
                    callee.getExpression().getText() === 'test';
                if (isTestDescribe)
                    return false;
            }
            return true;
        }
        // Keep other top-level declarations (constants, helper funcs, etc.)
        return true;
    });
    return keptStatements
        .map((s) => s.getText())
        .join('\n\n')
        .trim();
}
function renderDescribeBlock(args) {
    const lines = [];
    lines.push(`test.describe('${escapeSingleQuotes(args.describeTitle)} - ${escapeSingleQuotes(args.strategySlug)} - (negative) generated', () => {`);
    if (args.beforeEachText) {
        lines.push(indentBlock(dedent(args.beforeEachText), 2));
    }
    if (args.afterEachText) {
        lines.push(indentBlock(dedent(args.afterEachText), 2));
    }
    for (const testText of args.tests) {
        lines.push(indentBlock(testText, 2));
    }
    lines.push('});');
    return lines.join('\n\n');
}
function indentBlock(text, spaces) {
    const prefix = ' '.repeat(spaces);
    return text
        .split('\n')
        .map((line) => (line.trim().length === 0 ? line : prefix + line))
        .join('\n');
}
function dedent(text) {
    const lines = text.replace(/\r\n/g, '\n').split('\n');
    const nonEmpty = lines.filter((l) => l.trim().length > 0);
    if (nonEmpty.length === 0)
        return text.trim();
    const minIndent = Math.min(...nonEmpty.map((l) => {
        const match = l.match(/^\s*/);
        return match ? match[0].length : 0;
    }));
    return lines
        .map((l) => l.slice(minIndent))
        .join('\n')
        .trim();
}
function escapeSingleQuotes(value) {
    return value.replaceAll("'", "\\'");
}
