/**
 * App Config Extractor
 *
 * Extracts analytics and workbench config from the user's createApp() call
 * in app.ts. This is the v2 approach where createApp() is the single source
 * of truth for runtime configuration (replacing agentuity.config.ts).
 *
 * Uses TypeScript's compiler API to reliably detect and extract values.
 */
import ts from 'typescript';
import { join } from 'node:path';
/**
 * Extract analytics and workbench config from a createApp() call.
 *
 * Uses TypeScript AST to find `createApp({ ... })` and extract the values
 * of the `analytics` and `workbench` properties.
 */
function extractCreateAppConfig(sourceFile) {
    const result = {};
    // Walk the AST looking for createApp({ ... }) calls
    function visit(node) {
        // Check for createApp(...) call
        if (ts.isCallExpression(node) &&
            ts.isIdentifier(node.expression) &&
            node.expression.text === 'createApp' &&
            node.arguments.length > 0) {
            const firstArg = node.arguments[0];
            if (!firstArg)
                return;
            if (ts.isObjectLiteralExpression(firstArg)) {
                // Found createApp({ ... }) — extract properties
                for (const prop of firstArg.properties) {
                    if (!ts.isPropertyAssignment(prop))
                        continue;
                    const name = ts.isIdentifier(prop.name) ? prop.name.text : undefined;
                    if (!name)
                        continue;
                    // prop.initializer should always exist for PropertyAssignment, but check to satisfy TS
                    if (!('initializer' in prop))
                        continue;
                    const initializer = prop.initializer;
                    if (name === 'analytics') {
                        const value = extractValue(initializer);
                        if (value !== undefined) {
                            if (typeof value === 'boolean') {
                                result.analytics = value;
                            }
                            else if (typeof value === 'object') {
                                result.analytics = value;
                            }
                            // Ignore string/number for analytics
                        }
                    }
                    else if (name === 'workbench') {
                        const value = extractValue(initializer);
                        if (value !== undefined) {
                            if (typeof value === 'boolean' || typeof value === 'string') {
                                result.workbench = value;
                            }
                            else if (typeof value === 'object') {
                                result.workbench = value;
                            }
                            // Ignore number for workbench
                        }
                    }
                }
            }
        }
        ts.forEachChild(node, visit);
    }
    visit(sourceFile);
    return result;
}
/**
 * Extract a JavaScript value from a TypeScript AST expression node.
 * Handles: boolean literals, string literals, numeric literals,
 * object literals (as Record), and identifier references (by name).
 */
function extractValue(node) {
    if (ts.isLiteralExpression(node)) {
        // String literal or numeric literal
        if (ts.isStringLiteral(node)) {
            return node.text;
        }
        if (ts.isNumericLiteral(node)) {
            return Number(node.text);
        }
    }
    if (node.kind === ts.SyntaxKind.TrueKeyword) {
        return true;
    }
    if (node.kind === ts.SyntaxKind.FalseKeyword) {
        return false;
    }
    if (ts.isIdentifier(node)) {
        // Return the identifier name (e.g., a variable reference)
        return node.text;
    }
    if (ts.isObjectLiteralExpression(node)) {
        const obj = {};
        for (const prop of node.properties) {
            if (!ts.isPropertyAssignment(prop))
                continue;
            if (!ts.isIdentifier(prop.name))
                continue;
            const key = prop.name.text;
            obj[key] = extractValue(prop.initializer);
        }
        return obj;
    }
    return undefined;
}
/**
 * Detect and extract analytics/workbench config from app.ts.
 *
 * This is the v2 approach: runtime config lives in createApp() only.
 * The CLI reads these values at build time via AST parsing.
 */
export async function extractAppConfig(rootDir, logger) {
    // Look for app.ts in root first, then src/
    let appFile = join(rootDir, 'app.ts');
    if (!(await Bun.file(appFile).exists())) {
        appFile = join(rootDir, 'src', 'app.ts');
        if (!(await Bun.file(appFile).exists())) {
            logger.trace('[config-extract] No app.ts found');
            return {};
        }
    }
    try {
        const source = await Bun.file(appFile).text();
        // Quick bail-out before parsing
        if (!source.includes('createApp')) {
            logger.trace('[config-extract] No createApp call in %s', appFile);
            return {};
        }
        // Parse with TypeScript
        const sourceFile = ts.createSourceFile(appFile, source, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
        const config = extractCreateAppConfig(sourceFile);
        if (config.analytics !== undefined) {
            logger.debug('[config-extract] Found analytics in createApp(): %o', config.analytics);
        }
        if (config.workbench !== undefined) {
            logger.debug('[config-extract] Found workbench in createApp(): %o', config.workbench);
        }
        return config;
    }
    catch (error) {
        logger.warn('[config-extract] Failed to parse app.ts:', error);
        return {};
    }
}
//# sourceMappingURL=app-config-extractor.js.map