/**
 * V3.1 Inference Engine - Entry Point
 * Exports complete inference engine functionality
 */
// Core inference engine
export * from './core/index.js';
// Logical inference capabilities
export * from './logical/index.js';
// Deployment inference capabilities
export * from './deployment/index.js';
// Comprehensive inference engine
export { ComprehensiveInferenceEngine } from './comprehensive-engine.js';
// Dev specly generator
export { generateDevSpecly } from './dev-specly-generator.js';
// Specly format converter
import { SpeclyConverter } from './core/specly-converter.js';
// Dev specly generator
import { generateDevSpecly } from './dev-specly-generator.js';
// Quint → TypeScript transpiler
export { transpileEntityGuards, extractStateVariables, transpileQuintFile, generateGuardsModule } from './quint-transpiler.js';
export { verifySpec, buildSnapshot, formatVerificationResult } from './verification.js';
export { transpileActions, generateActionsModule } from './quint-transpiler.js';
import { ComprehensiveInferenceEngine } from './comprehensive-engine.js';
class SpecVerseInferenceEngine {
    name = 'inference';
    version = '3.5.2';
    capabilities = ['infer', 'logical-inference', 'deployment-inference', 'rule-engine'];
    _engine = null;
    async initialize(config) {
        this._engine = new ComprehensiveInferenceEngine(config?.options || {}, config?.debug || false);
    }
    getInfo() {
        return { name: this.name, version: this.version, capabilities: this.capabilities };
    }
    async loadRules() {
        if (!this._engine)
            throw new Error('Inference engine not initialized.');
        return this._engine.loadRules();
    }
    async infer(ast, options) {
        if (!this._engine)
            throw new Error('Inference engine not initialized.');
        await this._engine.loadRules();
        const components = ast.components || [];
        // Find the first component that has models — that's what we run inference on
        const inferTargetIndex = components.findIndex((c) => c.models && c.models.length > 0);
        let inferredComponent = null;
        let result = null;
        if (inferTargetIndex >= 0) {
            const targetComp = components[inferTargetIndex];
            // Convert AST ModelSpec[] to inference ModelDefinition[]
            const models = (targetComp.models || []).map((model) => ({
                name: model.name,
                attributes: (model.attributes || []).map((attr) => ({
                    name: attr.name,
                    type: attr.type || 'String',
                    required: attr.required || false,
                    unique: attr.unique || false,
                    default: attr.default,
                    auto: attr.auto,
                    category: attr.category,
                })),
                relationships: (model.relationships || []).map((rel) => ({
                    name: rel.name,
                    type: rel.type,
                    targetModel: rel.target,
                    cascadeDelete: rel.cascade || false,
                })),
                lifecycle: model.lifecycles?.[0] ? {
                    name: model.lifecycles[0].name,
                    states: model.lifecycles[0].states || [],
                    transitions: Object.entries(model.lifecycles[0].transitions || {}).map(([name, trans]) => ({
                        name, from: trans.from, to: trans.to, conditions: trans.condition ? [trans.condition] : [],
                    })),
                } : undefined,
                behaviors: model.behaviors ? Object.entries(model.behaviors).map(([name, b]) => ({
                    name, description: b.description, parameters: b.parameters, returns: b.returns,
                    requires: b.requires, ensures: b.ensures, publishes: b.publishes,
                })) : [],
                profiles: [],
                metadata: model.metadata || {},
            }));
            // Collect extension entity data
            const extensionData = {};
            if (targetComp.promotions)
                extensionData.promotions = targetComp.promotions;
            const compName = targetComp.name || 'Generated';
            result = await this._engine.inferCompleteSpecification(models, compName, options?.targetEnvironment || 'development', extensionData);
            // Merge inferred result with original component metadata and passthrough sections
            inferredComponent = { ...result.component, name: compName };
            if (targetComp.version)
                inferredComponent.version = String(targetComp.version);
            if (targetComp.description)
                inferredComponent.description = targetComp.description;
            // Copy sections that inference doesn't generate from the original component
            // Merge: original spec sections take priority over empty inferred ones
            for (const [key, value] of Object.entries(targetComp)) {
                if (key === 'name' || key === 'models' || value == null)
                    continue;
                const existing = inferredComponent[key];
                const isEmpty = !existing || (typeof existing === 'object' && !Array.isArray(existing) && Object.keys(existing).length === 0)
                    || (Array.isArray(existing) && existing.length === 0);
                if (isEmpty) {
                    inferredComponent[key] = value;
                }
            }
        }
        // Build YAML output: components header written once, each component appended
        let yamlOutput = 'components:\n';
        for (let i = 0; i < components.length; i++) {
            const comp = components[i];
            const compName = comp.name || `Component${i}`;
            if (i === inferTargetIndex && inferredComponent) {
                // This is the inferred component — serialize via SpeclyConverter
                // SpeclyConverter.toSpecly() outputs "components:\n  Name:\n  ..." so we strip the header
                const fullSpecly = SpeclyConverter.toSpecly(inferredComponent, compName);
                const withoutHeader = fullSpecly.replace(/^components:\n/, '');
                yamlOutput += withoutHeader + '\n';
            }
            else {
                // Passthrough component — serialize all its sections via SpeclyConverter
                const passComp = {};
                for (const [key, value] of Object.entries(comp)) {
                    if (key !== 'name' && value != null) {
                        passComp[key] = value;
                    }
                }
                const fullSpecly = SpeclyConverter.toSpecly(passComp, compName);
                const withoutHeader = fullSpecly.replace(/^components:\n/, '');
                yamlOutput += withoutHeader + '\n';
            }
        }
        // Append deployments
        if (result?.deployments && Object.keys(result.deployments).length > 0) {
            const yaml = await import('js-yaml');
            yamlOutput += '\ndeployments:\n';
            yamlOutput += yaml.dump(result.deployments, { indent: 2, lineWidth: -1, noRefs: true })
                .split('\n').map((l) => l ? '  ' + l : '').join('\n');
        }
        else if (ast.deployments && ast.deployments.length > 0) {
            // Preserve original deployments
            const yaml = await import('js-yaml');
            const deploymentsObj = {};
            for (const dep of ast.deployments) {
                const { name, ...rest } = dep;
                if (name)
                    deploymentsObj[name] = rest;
            }
            yamlOutput += '\ndeployments:\n';
            yamlOutput += yaml.dump(deploymentsObj, { indent: 2, lineWidth: -1, noRefs: true })
                .split('\n').map((l) => l ? '  ' + l : '').join('\n');
        }
        else if (ast.deployments !== undefined) {
            // Preserve empty deployments
            yamlOutput += '\ndeployments: {}\n';
        }
        // Generate dev.specly for runtime DevShell
        const devYaml = inferredComponent
            ? generateDevSpecly(inferredComponent, inferredComponent.name)
            : undefined;
        return {
            component: inferredComponent || {},
            deployments: result?.deployments || {},
            yaml: yamlOutput.trim(),
            devYaml,
            validation: result?.validation || { valid: true, errors: [], warnings: [] },
            statistics: {
                ...(result?.statistics || {}),
                rulesApplied: result?.statistics?.totalRulesApplied || 0,
            },
        };
    }
}
export const engine = new SpecVerseInferenceEngine();
export default engine;
//# sourceMappingURL=index.js.map