/**
 * Application - Framework core entry point
 * Handles application lifecycle, booting, and environment
 */
import { appConfig } from '../config/index.js';
import { ServiceContainer } from '../container/ServiceContainer.js';
import { MiddlewareStack } from '../middleware/MiddlewareStack.js';
import { Router } from '../routes/Router.js';
import { createLifecycle, registerFrameworkShutdownHooks } from './registry/runtime.js';
const ShutdownManager = Object.freeze({
    create() {
        const hooks = [];
        return Object.freeze({
            add(hook) {
                hooks.push(hook);
            },
            async run() {
                // Run hooks in parallel for better performance
                await Promise.all(hooks.map(async (hook) => hook()));
            },
        });
    },
});
const resolveBasePath = (basePath) => {
    if (typeof basePath === 'string')
        return basePath;
    if (typeof process !== 'undefined' && typeof process.cwd === 'function')
        return process.cwd();
    return '';
};
const makeJoinFromBase = (resolvedBasePath) => (subPath) => {
    return resolvedBasePath.length > 0 ? `${resolvedBasePath}/${subPath}` : subPath;
};
const registerCorePaths = (container, resolvedBasePath, joinFromBase) => {
    container.singleton('paths', {
        base: resolvedBasePath,
        app: joinFromBase('app'),
        config: joinFromBase('config'),
        database: joinFromBase('database'),
        routes: joinFromBase('routes'),
        tests: joinFromBase('tests'),
    });
};
const registerCoreInstances = (params) => {
    params.container.singleton('env', params.environment);
    params.container.singleton('router', params.router);
    params.container.singleton('middleware', params.middlewareStack);
    params.container.singleton('container', params.container);
    params.container.singleton('shutdownManager', params.shutdownManager);
};
/**
 * Application Factory
 */
export const Application = Object.freeze({
    /**
     * Create a new application instance
     */
    create(basePath) {
        const resolvedBasePath = resolveBasePath(basePath);
        const joinFromBase = makeJoinFromBase(resolvedBasePath);
        const environment = appConfig.environment;
        const container = ServiceContainer.create();
        const router = Router.createRouter();
        const middlewareStack = MiddlewareStack.create();
        const shutdownManager = ShutdownManager.create();
        let booted = false;
        registerCorePaths(container, resolvedBasePath, joinFromBase);
        registerCoreInstances({ container, environment, router, middlewareStack, shutdownManager });
        registerFrameworkShutdownHooks(shutdownManager);
        const { boot, shutdown } = createLifecycle({
            environment,
            resolvedBasePath,
            router,
            shutdownManager,
            getBooted: () => booted,
            setBooted: (value) => {
                booted = value;
            },
        });
        return {
            boot,
            shutdown,
            isBooted: () => booted,
            isDevelopment: () => appConfig.isDevelopment(),
            isProduction: () => appConfig.isProduction(),
            isTesting: () => appConfig.isTesting(),
            getEnvironment: () => environment,
            getRouter: () => router,
            getContainer: () => container,
            getMiddlewareStack: () => middlewareStack,
            getBasePath: () => resolvedBasePath,
        };
    },
});
export default Application;
