/**
 * Build metadata utilities
 * Provides cached access to agentuity.metadata.json
 */
var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
    if (typeof path === "string" && /^\.\.?\//.test(path)) {
        return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
            return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
        });
    }
    return path;
};
import { join } from 'node:path';
import { existsSync, readFileSync } from 'node:fs';
import { internal } from './logger/internal';
// Cached metadata - null means not yet loaded, undefined means file not found
let _metadataCache = null;
/**
 * Get the path to agentuity.metadata.json
 *
 * Checks multiple locations to support both dev and production:
 * - Production: cwd is .agentuity/, file is at cwd/agentuity.metadata.json
 * - Dev: cwd is project root, file is at cwd/.agentuity/agentuity.metadata.json
 */
export function getMetadataPath() {
    if (process.env.AGENTUITY_PROJECT_DIR) {
        // Dev path: running from project root with env flag to a different path using --dir
        const devPath = join(process.env.AGENTUITY_PROJECT_DIR, '.agentuity', 'agentuity.metadata.json');
        if (existsSync(devPath)) {
            return devPath;
        }
    }
    // Production path: running from .agentuity/ directory
    const productionPath = join(process.cwd(), 'agentuity.metadata.json');
    if (existsSync(productionPath)) {
        return productionPath;
    }
    // Dev path: running from project root
    const devPath = join(process.cwd(), '.agentuity', 'agentuity.metadata.json');
    if (existsSync(devPath)) {
        return devPath;
    }
    // Default to production path (will fail gracefully in loadBuildMetadata)
    return productionPath;
}
/**
 * Load and cache the build metadata from agentuity.metadata.json
 * Returns undefined if the file doesn't exist or can't be parsed
 */
export function loadBuildMetadata() {
    // Return cached value if already loaded
    if (_metadataCache !== null) {
        internal.info('[metadata] loadBuildMetadata: returning cached value (exists: %s)', _metadataCache !== undefined);
        return _metadataCache;
    }
    const metadataPath = getMetadataPath();
    internal.info('[metadata] loadBuildMetadata: checking path %s', metadataPath);
    internal.info('[metadata] loadBuildMetadata: cwd=%s', process.cwd());
    if (!existsSync(metadataPath)) {
        internal.info('[metadata] agentuity.metadata.json not found at %s', metadataPath);
        // In dev mode, don't cache "not found" — the dev server generates
        // the metadata file after createApp() has already been called.
        // Caching undefined would permanently prevent the workbench from
        // finding agents once the file is later written.
        if (process.env.NODE_ENV === 'development') {
            return undefined;
        }
        _metadataCache = undefined;
        return undefined;
    }
    try {
        internal.info('[metadata] loadBuildMetadata: file exists, reading...');
        const content = readFileSync(metadataPath, 'utf-8');
        const metadata = JSON.parse(content);
        _metadataCache = metadata;
        // Log agent and eval counts
        let totalEvals = 0;
        for (const agent of metadata.agents ?? []) {
            totalEvals += agent.evals?.length ?? 0;
        }
        internal.info('[metadata] loaded agentuity.metadata.json: %d agents, %d routes, %d total evals', metadata.agents?.length ?? 0, metadata.routes?.length ?? 0, totalEvals);
        // Log agent names and their eval counts
        for (const agent of metadata.agents ?? []) {
            internal.info('[metadata]   agent: %s (evals: %d)', agent.name, agent.evals?.length ?? 0);
        }
        return metadata;
    }
    catch (err) {
        internal.info('[metadata] failed to load agentuity.metadata.json: %s', err);
        _metadataCache = undefined;
        return undefined;
    }
}
// Agent lookup cache - built lazily from metadata
let _agentsByName = null;
let _agentsByAgentId = null;
// Eval lookup cache - nested map: agentName -> evalName -> evalMetadata
let _evalsByAgentName = null;
let _evalsByAgentId = null;
// Track if we've already attempted a reload for empty eval map
let _evalReloadAttempted = false;
// Track if we've already attempted a reload for empty agent map
let _agentReloadAttempted = false;
/**
 * Build agent lookup maps from metadata
 */
function ensureAgentMaps() {
    if (_agentsByName !== null) {
        internal.info(`[metadata] ensureAgentMaps: already initialized, skipping`);
        return;
    }
    internal.info(`[metadata] ensureAgentMaps: initializing agent and eval maps`);
    _agentsByName = new Map();
    _agentsByAgentId = new Map();
    _evalsByAgentName = new Map();
    _evalsByAgentId = new Map();
    const metadata = loadBuildMetadata();
    if (!metadata?.agents) {
        internal.info(`[metadata] ensureAgentMaps: no metadata or no agents found`);
        // In dev mode, don't cache empty maps — metadata file may appear later
        if (process.env.NODE_ENV === 'development') {
            _agentsByName = null;
            _agentsByAgentId = null;
            _evalsByAgentName = null;
            _evalsByAgentId = null;
        }
        return;
    }
    internal.info(`[metadata] ensureAgentMaps: processing ${metadata.agents.length} agents`);
    for (const agent of metadata.agents) {
        if (agent.name) {
            _agentsByName.set(agent.name, agent);
        }
        if (agent.agentId) {
            _agentsByAgentId.set(agent.agentId, agent);
        }
        // Build eval lookup maps
        if (agent.evals && agent.evals.length > 0) {
            const evalsByName = new Map();
            for (const evalMeta of agent.evals) {
                if (evalMeta.name) {
                    evalsByName.set(evalMeta.name, evalMeta);
                    internal.info(`[metadata] Indexed eval: agent='${agent.name}' eval='${evalMeta.name}' identifier='${evalMeta.identifier}'`);
                }
            }
            if (agent.name) {
                _evalsByAgentName.set(agent.name, evalsByName);
            }
            if (agent.agentId) {
                _evalsByAgentId.set(agent.agentId, evalsByName);
            }
        }
        else {
            internal.info(`[metadata] Agent '${agent.name}' has no evals`);
        }
    }
    internal.info(`[metadata] Eval maps built: ${_evalsByAgentName?.size ?? 0} agents with evals`);
}
/**
 * Look up agent metadata by name
 */
export function getAgentMetadataByName(agentName) {
    ensureAgentMaps();
    // If agent map is empty, the cache may have been built before metadata was ready
    // Try clearing and reloading once (only attempt once to avoid repeated reloads)
    // This mirrors the reload logic in getEvalMetadata
    if (_agentsByName?.size === 0 && !_agentReloadAttempted) {
        _agentReloadAttempted = true;
        internal.info(`[metadata] getAgentMetadataByName: agent map is empty, attempting cache clear and reload`);
        clearMetadataCache();
        ensureAgentMaps();
        internal.info(`[metadata] getAgentMetadataByName: after reload, agent map size: ${_agentsByName?.size ?? 0}`);
    }
    return _agentsByName?.get(agentName);
}
/**
 * Look up agent metadata by agentId
 */
export function getAgentMetadataByAgentId(agentId) {
    ensureAgentMaps();
    return _agentsByAgentId?.get(agentId);
}
/**
 * Look up eval metadata by agent name and eval name
 */
export function getEvalMetadata(agentName, evalName) {
    ensureAgentMaps();
    // If eval map is empty, the cache may have been built before metadata was ready
    // Try clearing and reloading once (only attempt once to avoid repeated reloads)
    if (_evalsByAgentName?.size === 0 && !_evalReloadAttempted) {
        _evalReloadAttempted = true;
        internal.info(`[metadata] getEvalMetadata: eval map is empty, attempting cache clear and reload`);
        clearMetadataCache();
        ensureAgentMaps();
        internal.info(`[metadata] getEvalMetadata: after reload, eval map size: ${_evalsByAgentName?.size ?? 0}`);
    }
    const agentEvals = _evalsByAgentName?.get(agentName);
    internal.info(`[metadata] getEvalMetadata('${agentName}', '${evalName}'): agentEvals=${agentEvals ? `Map(${agentEvals.size})` : 'undefined'}`);
    if (agentEvals) {
        internal.info(`[metadata] Available evals for agent '${agentName}': [${[...agentEvals.keys()].join(', ')}]`);
    }
    if (!agentEvals) {
        internal.info(`[metadata] Available agents in eval map: [${[...(_evalsByAgentName?.keys() ?? [])].join(', ')}]`);
    }
    const result = agentEvals?.get(evalName);
    internal.info(`[metadata] getEvalMetadata result: ${result ? `found identifier=${result.identifier}` : 'not found'}`);
    return result;
}
/**
 * Look up eval metadata by agentId and eval name
 */
export function getEvalMetadataByAgentId(agentId, evalName) {
    ensureAgentMaps();
    return _evalsByAgentId?.get(agentId)?.get(evalName);
}
/**
 * Check if metadata file exists (uses cache)
 */
export function hasMetadata() {
    return loadBuildMetadata() !== undefined;
}
// Track if agents have been imported
let _agentsImported = false;
/**
 * Import all agents from metadata filenames to ensure they're registered.
 * This is needed so that runtime schemas are available for JSON schema generation.
 * Safe to call multiple times - will only import once.
 */
export async function ensureAgentsImported() {
    if (_agentsImported) {
        return;
    }
    const metadata = loadBuildMetadata();
    if (!metadata?.agents?.length) {
        _agentsImported = true;
        return;
    }
    internal.info('[metadata] ensureAgentsImported: importing %d agents', metadata.agents.length);
    for (const agent of metadata.agents) {
        if (!agent.filename) {
            continue;
        }
        try {
            // Convert relative filename to absolute path from cwd
            const absolutePath = join(process.cwd(), agent.filename);
            internal.info('[metadata] importing agent: %s from %s', agent.name, absolutePath);
            await import(__rewriteRelativeImportExtension(absolutePath));
        }
        catch (err) {
            internal.info('[metadata] failed to import agent %s: %s', agent.name, err);
        }
    }
    _agentsImported = true;
}
/**
 * Clear the metadata cache (useful for testing or hot reload)
 */
export function clearMetadataCache() {
    internal.info('[metadata] clearMetadataCache: clearing all caches');
    _metadataCache = null;
    _agentsByName = null;
    _agentsByAgentId = null;
    _evalsByAgentName = null;
    _evalsByAgentId = null;
    // Note: _evalReloadAttempted is intentionally NOT reset here
    // to prevent infinite reload loops in getEvalMetadata
}
//# sourceMappingURL=_metadata.js.map