"use strict";
/**
 * Lazy Loading Generator Registry
 * Loads generators on-demand to improve startup performance
 */
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.LazyGeneratorRegistry = void 0;
exports.createLazyRegistry = createLazyRegistry;
/**
 * Lazy-loading wrapper for GeneratorRegistry
 * Only loads generators when they're actually needed
 */
class LazyGeneratorRegistry {
    registry;
    loaders = new Map();
    loadTimes = new Map();
    constructor(baseRegistry) {
        this.registry = baseRegistry;
    }
    /**
     * Register a generator with lazy loading
     */
    registerLazy(id, category, factory) {
        this.loaders.set(id, {
            id,
            category,
            factory,
            loaded: false,
        });
    }
    /**
     * Get a generator by ID, loading it if necessary
     */
    async getGenerator(id) {
        const loader = this.loaders.get(id);
        if (!loader) {
            // Try custom generators from base registry
            return this.registry.getCustomGenerator(id);
        }
        // Load generator if not already loaded
        if (!loader.loaded) {
            await this.loadGenerator(loader);
        }
        return loader.instance;
    }
    /**
     * Get frontend generator (lazy load)
     */
    async getFrontendGenerator(framework) {
        // Try to find in lazy loaders first
        for (const loader of this.loaders.values()) {
            if (loader.category === 'frontend') {
                if (!loader.loaded) {
                    await this.loadGenerator(loader);
                }
                if (loader.instance?.id === framework || loader.instance.framework === framework) {
                    return loader.instance;
                }
            }
        }
        // Fall back to base registry
        return this.registry.getFrontendGenerator(framework);
    }
    /**
     * Get backend generator (lazy load)
     */
    async getBackendGenerator(language, framework) {
        // Try to find in lazy loaders first
        for (const loader of this.loaders.values()) {
            if (loader.category === 'backend') {
                if (!loader.loaded) {
                    await this.loadGenerator(loader);
                }
                const gen = loader.instance;
                if (gen && this.matchesBackendCriteria(gen, language, framework)) {
                    return gen;
                }
            }
        }
        // Fall back to base registry
        if (!language) {
            return undefined;
        }
        return this.registry.getBackendGenerator(language, framework);
    }
    /**
     * Get database generator (lazy load)
     */
    async getDatabaseGenerator(technology) {
        // Try to find in lazy loaders first
        for (const loader of this.loaders.values()) {
            if (loader.category === 'database') {
                if (!loader.loaded) {
                    await this.loadGenerator(loader);
                }
                if (loader.instance?.id === technology) {
                    return loader.instance;
                }
            }
        }
        // Fall back to base registry
        return this.registry.getDatabaseGenerator(technology);
    }
    /**
     * Get test generator (lazy load)
     */
    async getTestGenerator(framework) {
        // Try to find in lazy loaders first
        for (const loader of this.loaders.values()) {
            if (loader.category === 'test') {
                if (!loader.loaded) {
                    await this.loadGenerator(loader);
                }
                if (loader.instance?.id === framework) {
                    return loader.instance;
                }
            }
        }
        // Fall back to base registry
        return this.registry.getTestGenerator(framework);
    }
    /**
     * Get all custom generators (lazy load all)
     */
    async getCustomGenerators() {
        const generators = [];
        const seenIds = new Set();
        // Load all custom generators from lazy loaders
        for (const loader of this.loaders.values()) {
            if (loader.category === 'custom') {
                if (!loader.loaded) {
                    await this.loadGenerator(loader);
                }
                if (loader.instance) {
                    generators.push(loader.instance);
                    seenIds.add(loader.instance.id);
                }
            }
        }
        // Add from base registry (excluding already loaded ones)
        for (const gen of this.registry.getCustomGenerators()) {
            if (!seenIds.has(gen.id)) {
                generators.push(gen);
            }
        }
        return generators;
    }
    /**
     * Preload specific generators (for performance-critical paths)
     */
    async preload(ids) {
        const promises = [];
        for (const id of ids) {
            const loader = this.loaders.get(id);
            if (loader && !loader.loaded) {
                promises.push(this.loadGenerator(loader));
            }
        }
        await Promise.all(promises);
    }
    /**
     * Preload all generators (useful for warming up)
     */
    async preloadAll() {
        const promises = [];
        for (const loader of this.loaders.values()) {
            if (!loader.loaded) {
                promises.push(this.loadGenerator(loader));
            }
        }
        await Promise.all(promises);
    }
    /**
     * Load a specific generator
     */
    async loadGenerator(loader) {
        if (loader.loaded) {
            return;
        }
        const startTime = Date.now();
        try {
            const instance = await Promise.resolve(loader.factory());
            loader.instance = instance;
            const loadTime = Date.now() - startTime;
            this.loadTimes.set(loader.id, loadTime);
            loader.loaded = true;
            // Register with base registry for compatibility
            // Use type assertions based on category since factory ensures correct type
            switch (loader.category) {
                case 'frontend':
                    this.registry.registerFrontendGenerator(instance);
                    break;
                case 'backend':
                    this.registry.registerBackendGenerator(instance);
                    break;
                case 'database':
                    this.registry.registerDatabaseGenerator(instance);
                    break;
                case 'test':
                    this.registry.registerTestGenerator(instance);
                    break;
                case 'documentation':
                    this.registry.registerDocumentationGenerator(instance);
                    break;
                case 'cli':
                    this.registry.registerCliGenerator(instance);
                    break;
                case 'custom':
                    this.registry.registerCustomGenerator(instance);
                    break;
            }
        }
        catch (error) {
            console.error(`Failed to load generator "${loader.id}":`, error);
            loader.loaded = true; // Mark as loaded to prevent retry loops
        }
    }
    /**
     * Check if generator matches backend criteria
     */
    matchesBackendCriteria(generator, language, framework) {
        const gen = generator;
        if (language && gen.language !== language) {
            return false;
        }
        if (framework && gen.framework !== framework) {
            return false;
        }
        return true;
    }
    /**
     * Get loading statistics
     */
    getLoadStats() {
        const total = this.loaders.size;
        const loaded = Array.from(this.loaders.values()).filter(l => l.loaded).length;
        const pending = total - loaded;
        const totalLoadTime = Array.from(this.loadTimes.values()).reduce((sum, time) => sum + time, 0);
        const averageLoadTime = loaded > 0 ? totalLoadTime / loaded : 0;
        return {
            total,
            loaded,
            pending,
            totalLoadTime,
            averageLoadTime,
            loadTimes: new Map(this.loadTimes),
        };
    }
    /**
     * Check if a generator is loaded
     */
    isLoaded(id) {
        const loader = this.loaders.get(id);
        return loader ? loader.loaded : false;
    }
    /**
     * Get list of all registered generator IDs
     */
    listGeneratorIds() {
        return Array.from(this.loaders.keys());
    }
    /**
     * Get list of loaded generator IDs
     */
    listLoadedGeneratorIds() {
        return Array.from(this.loaders.values())
            .filter(l => l.loaded)
            .map(l => l.id);
    }
    /**
     * Get list of pending generator IDs
     */
    listPendingGeneratorIds() {
        return Array.from(this.loaders.values())
            .filter(l => !l.loaded)
            .map(l => l.id);
    }
    /**
     * Get the underlying base registry (for compatibility)
     */
    getBaseRegistry() {
        return this.registry;
    }
}
exports.LazyGeneratorRegistry = LazyGeneratorRegistry;
/**
 * Create lazy registry with standard generators
 */
function createLazyRegistry(baseRegistry) {
    const lazyRegistry = new LazyGeneratorRegistry(baseRegistry);
    // Register all standard generators with lazy loading
    lazyRegistry.registerLazy('react', 'frontend', async () => {
        const { ReactGenerator } = await Promise.resolve().then(() => __importStar(require('./frontend/react-generator')));
        return new ReactGenerator();
    });
    lazyRegistry.registerLazy('typescript-express', 'backend', async () => {
        const { TypeScriptExpressGenerator } = await Promise.resolve().then(() => __importStar(require('./backend/typescript-express-generator')));
        return new TypeScriptExpressGenerator();
    });
    lazyRegistry.registerLazy('typescript-cli', 'cli', async () => {
        const { TypeScriptCliGenerator } = await Promise.resolve().then(() => __importStar(require('./cli/typescript-cli-generator')));
        return new TypeScriptCliGenerator();
    });
    lazyRegistry.registerLazy('prisma', 'database', async () => {
        const { PrismaGenerator } = await Promise.resolve().then(() => __importStar(require('./database/prisma-generator')));
        return new PrismaGenerator();
    });
    lazyRegistry.registerLazy('drizzle', 'database', async () => {
        const { DrizzleGenerator } = await Promise.resolve().then(() => __importStar(require('./database/drizzle-generator')));
        return new DrizzleGenerator();
    });
    lazyRegistry.registerLazy('vitest', 'test', async () => {
        const { FrontendTestGenerator } = await Promise.resolve().then(() => __importStar(require('./test/frontend-test-generator')));
        return new FrontendTestGenerator();
    });
    lazyRegistry.registerLazy('jest', 'test', async () => {
        const { BackendTestGenerator } = await Promise.resolve().then(() => __importStar(require('./test/backend-test-generator')));
        return new BackendTestGenerator();
    });
    lazyRegistry.registerLazy('playwright', 'test', async () => {
        const { E2ETestGenerator } = await Promise.resolve().then(() => __importStar(require('./test/e2e-test-generator')));
        return new E2ETestGenerator();
    });
    lazyRegistry.registerLazy('cli-jest', 'test', async () => {
        const { CliTestGenerator } = await Promise.resolve().then(() => __importStar(require('./test/cli-test-generator')));
        return new CliTestGenerator();
    });
    lazyRegistry.registerLazy('markdown', 'documentation', async () => {
        const { MarkdownDocumentationGenerator } = await Promise.resolve().then(() => __importStar(require('./docs/markdown-generator')));
        return new MarkdownDocumentationGenerator();
    });
    lazyRegistry.registerLazy('github-actions', 'custom', async () => {
        const { GitHubActionsGenerator } = await Promise.resolve().then(() => __importStar(require('./ci-cd/github-actions-generator')));
        return new GitHubActionsGenerator();
    });
    lazyRegistry.registerLazy('environment', 'custom', async () => {
        const { EnvironmentGenerator } = await Promise.resolve().then(() => __importStar(require('./env/environment-generator')));
        return new EnvironmentGenerator();
    });
    lazyRegistry.registerLazy('service', 'custom', async () => {
        const { ServiceGenerator } = await Promise.resolve().then(() => __importStar(require('./infrastructure/service-generator')));
        return new ServiceGenerator();
    });
    lazyRegistry.registerLazy('upstash-redis', 'custom', async () => {
        const { UpstashRedisGenerator } = await Promise.resolve().then(() => __importStar(require('./cache/upstash-redis-generator')));
        return new UpstashRedisGenerator();
    });
    lazyRegistry.registerLazy('readme', 'custom', async () => {
        const { ReadmeGenerator } = await Promise.resolve().then(() => __importStar(require('./readme-generator')));
        return new ReadmeGenerator();
    });
    lazyRegistry.registerLazy('event-types', 'custom', async () => {
        const { generateEventTypes } = await Promise.resolve().then(() => __importStar(require('./events/event-types-generator')));
        return {
            id: 'event-types',
            name: 'Event Types Generator',
            description: 'Generates TypeScript event type interfaces from YAML event definitions',
            generate: generateEventTypes,
        };
    });
    lazyRegistry.registerLazy('event-bus', 'custom', async () => {
        const { generateEventBus } = await Promise.resolve().then(() => __importStar(require('./events/event-bus-generator')));
        return {
            id: 'event-bus',
            name: 'Event Bus Generator',
            description: 'Generates Redis pub/sub event bus infrastructure for event-driven architecture',
            generate: generateEventBus,
        };
    });
    lazyRegistry.registerLazy('event-handlers', 'custom', async () => {
        const { generateEventHandlers } = await Promise.resolve().then(() => __importStar(require('./events/event-handlers-generator')));
        return {
            id: 'event-handlers',
            name: 'Event Handlers Generator',
            description: 'Generates event handler implementations for consuming services',
            generate: generateEventHandlers,
        };
    });
    lazyRegistry.registerLazy('websocket-server', 'custom', async () => {
        const { generateWebSocketServer } = await Promise.resolve().then(() => __importStar(require('./websocket/websocket-server-generator')));
        return {
            id: 'websocket-server',
            name: 'WebSocket Server Generator',
            description: 'Generates WebSocket server infrastructure for real-time updates',
            generate: generateWebSocketServer,
        };
    });
    lazyRegistry.registerLazy('websocket-client', 'custom', async () => {
        const { generateWebSocketClient } = await Promise.resolve().then(() => __importStar(require('./websocket/websocket-client-generator')));
        return {
            id: 'websocket-client',
            name: 'WebSocket Client Generator',
            description: 'Generates React hooks and utilities for WebSocket connections',
            generate: generateWebSocketClient,
        };
    });
    return lazyRegistry;
}
//# sourceMappingURL=lazy-registry.js.map