/* ────────────────────────────────────────────────────────────────
   Language Exporter — Base Classes and Type Mapping
   
   Abstract base for all language exporters with common
   infrastructure for code generation and type mapping.
──────────────────────────────────────────────────────────────── */
const defaultConfig = {
    indent: '    ',
    lineEnding: '\n',
    includeDebugComments: false,
    includeSourceMappings: false,
};
/* ── Code Builder ─────────────────────────────────────────────── */
class CodeBuilder {
    constructor(config) {
        this.lines = [];
        this.currentIndent = 0;
        this.indentStr = config.indent;
        this.lineEnding = config.lineEnding;
    }
    indent() {
        this.currentIndent++;
        return this;
    }
    dedent() {
        this.currentIndent = Math.max(0, this.currentIndent - 1);
        return this;
    }
    line(text = '') {
        const prefix = this.indentStr.repeat(this.currentIndent);
        this.lines.push(prefix + text);
        return this;
    }
    rawLine(text) {
        this.lines.push(text);
        return this;
    }
    emptyLine() {
        this.lines.push('');
        return this;
    }
    comment(text, style = 'line') {
        if (style === 'block') {
            this.line('/*');
            for (const l of text.split('\n')) {
                this.line(` * ${l}`);
            }
            this.line(' */');
        }
        else {
            for (const l of text.split('\n')) {
                this.line(`// ${l}`);
            }
        }
        return this;
    }
    docComment(text, style = 'jsdoc') {
        switch (style) {
            case 'csharp':
                this.line('/// <summary>');
                for (const l of text.split('\n')) {
                    this.line(`/// ${l}`);
                }
                this.line('/// </summary>');
                break;
            case 'python':
                this.line('"""');
                for (const l of text.split('\n')) {
                    this.line(l);
                }
                this.line('"""');
                break;
            case 'lua':
                this.line('---');
                for (const l of text.split('\n')) {
                    this.line(`--- ${l}`);
                }
                break;
            default: // jsdoc
                this.line('/**');
                for (const l of text.split('\n')) {
                    this.line(` * ${l}`);
                }
                this.line(' */');
        }
        return this;
    }
    block(open, close, body) {
        this.line(open);
        this.indent();
        body();
        this.dedent();
        this.line(close);
        return this;
    }
    toString() {
        return this.lines.join(this.lineEnding);
    }
    get lineCount() {
        return this.lines.length;
    }
}
/* ── Abstract Base Exporter ───────────────────────────────────── */
class LanguageExporter {
    constructor(config = {}) {
        this.errors = [];
        this.warnings = [];
        this.config = { ...defaultConfig, ...config };
    }
    /* ── Main Export Entry ──────────────────────────────────────── */
    export(script, config) {
        const startTime = performance.now();
        this.errors = [];
        this.warnings = [];
        if (config) {
            this.config = { ...this.config, ...config };
        }
        const files = [];
        let totalLines = 0;
        try {
            const content = this.generateScript(script);
            totalLines = content.split('\n').length;
            files.push({
                filename: `${script.name}.${this.fileExtension}`,
                path: `${script.name}.${this.fileExtension}`,
                content,
                language: this.languageName,
            });
        }
        catch (e) {
            this.addError(`Export failed: ${e instanceof Error ? e.message : String(e)}`);
        }
        return {
            files,
            errors: this.errors,
            warnings: this.warnings,
            stats: {
                classCount: script.classes.length,
                methodCount: script.classes.reduce((sum, c) => sum + c.methods.length, 0),
                lineCount: totalLines,
                exportDuration: performance.now() - startTime,
            },
        };
    }
    /* ── Protected Helpers ──────────────────────────────────────── */
    addError(message, nodeId) {
        this.errors.push({ message, nodeId });
    }
    addWarning(message, nodeId, suggestion) {
        this.warnings.push({ message, nodeId, suggestion });
    }
    mapType(typeInfo) {
        var _a, _b;
        const base = this.typeMapping[typeInfo.type] || typeInfo.customName || 'any';
        if (typeInfo.type === 'array' && ((_a = typeInfo.genericArgs) === null || _a === void 0 ? void 0 : _a[0])) {
            return this.formatArrayType(this.mapType(typeInfo.genericArgs[0]));
        }
        if (typeInfo.type === 'dictionary' && ((_b = typeInfo.genericArgs) === null || _b === void 0 ? void 0 : _b.length) === 2) {
            return this.formatDictType(this.mapType(typeInfo.genericArgs[0]), this.mapType(typeInfo.genericArgs[1]));
        }
        if (typeInfo.nullable) {
            return this.formatNullableType(base);
        }
        return base;
    }
    createBuilder() {
        return new CodeBuilder(this.config);
    }
    /* ── Virtual Methods (override for language specifics) ──────── */
    formatArrayType(elementType) {
        return `${elementType}[]`;
    }
    formatDictType(keyType, valueType) {
        return `Dictionary<${keyType}, ${valueType}>`;
    }
    formatNullableType(baseType) {
        return `${baseType}?`;
    }
    generateImport(_imp, _builder) {
        // Override per language
    }
    generateEnum(_en, _builder) {
        // Override per language
    }
    generateProperty(_prop, _builder) {
        // Override per language
    }
    generateSignal(_signal, _builder) {
        // Override per language
    }
}
/* ── Common Statement Generator ───────────────────────────────── */
class ImperativeLanguageExporter extends LanguageExporter {
    generateStatement(stmt, builder) {
        if (stmt.comment && this.config.includeDebugComments) {
            builder.comment(stmt.comment);
        }
        switch (stmt.kind) {
            case 'varDecl':
                this.generateVarDecl(stmt, builder);
                break;
            case 'assignment':
                this.generateAssignment(stmt, builder);
                break;
            case 'if':
                this.generateIf(stmt, builder);
                break;
            case 'while':
                this.generateWhile(stmt, builder);
                break;
            case 'for':
                this.generateFor(stmt, builder);
                break;
            case 'forEach':
                this.generateForEach(stmt, builder);
                break;
            case 'return':
                this.generateReturn(stmt, builder);
                break;
            case 'break':
                builder.line(this.breakKeyword + this.statementTerminator);
                break;
            case 'continue':
                builder.line(this.continueKeyword + this.statementTerminator);
                break;
            case 'expressionStatement':
                builder.line(this.generateExpression(stmt.expression) +
                    this.statementTerminator);
                break;
            case 'block':
                for (const s of stmt.statements) {
                    this.generateStatement(s, builder);
                }
                break;
            case 'switch':
                this.generateSwitch(stmt, builder);
                break;
            case 'try':
                this.generateTry(stmt, builder);
                break;
            default:
                this.addWarning(`Unsupported statement kind: ${stmt.kind}`);
        }
    }
    generateExpression(expr) {
        switch (expr.kind) {
            case 'literal':
                return this.generateLiteral(expr);
            case 'identifier':
                return expr.name;
            case 'binaryOp':
                return this.generateBinaryOp(expr);
            case 'unaryOp':
                return this.generateUnaryOp(expr);
            case 'call':
                return this.generateCall(expr);
            case 'methodCall':
                return this.generateMethodCall(expr);
            case 'propertyAccess':
                return this.generatePropertyAccess(expr);
            case 'indexAccess':
                return this.generateIndexAccess(expr);
            case 'conditional':
                return this.generateConditional(expr);
            case 'arrayLiteral':
                return this.generateArrayLiteral(expr);
            case 'dictionaryLiteral':
                return this.generateDictionaryLiteral(expr);
            case 'cast':
                return this.generateCast(expr);
            case 'lambda':
                return this.generateLambda(expr);
            case 'new':
                return this.generateNew(expr);
            default:
                this.addWarning(`Unsupported expression kind: ${expr.kind}`);
                return '/* unsupported */';
        }
    }
}
/* ── Utility Functions ────────────────────────────────────────── */
function escapeString(str, quote = '"') {
    return str
        .replace(/\\/g, '\\\\')
        .replace(new RegExp(quote, 'g'), '\\' + quote)
        .replace(/\n/g, '\\n')
        .replace(/\r/g, '\\r')
        .replace(/\t/g, '\\t');
}
function toUpperCamelCase(str) {
    return str
        .replace(/[-_\s]+(.)?/g, (_, c) => (c ? c.toUpperCase() : ''))
        .replace(/^(.)/, (c) => c.toUpperCase());
}
function toLowerCamelCase(str) {
    return str
        .replace(/[-_\s]+(.)?/g, (_, c) => (c ? c.toUpperCase() : ''))
        .replace(/^(.)/, (c) => c.toLowerCase());
}
function toSnakeCase(str) {
    return str
        .replace(/([a-z])([A-Z])/g, '$1_$2')
        .replace(/[-\s]+/g, '_')
        .toLowerCase();
}
function toScreamingSnakeCase(str) {
    return toSnakeCase(str).toUpperCase();
}

export { CodeBuilder, ImperativeLanguageExporter, LanguageExporter, defaultConfig, escapeString, toLowerCamelCase, toScreamingSnakeCase, toSnakeCase, toUpperCamelCase };
//# sourceMappingURL=LanguageExporter.js.map
