import * as globalConfigModule from './global/globalConfig.js';
import { loadGlobalConfigTraceState } from './global/globalConfigCore.js';
import { mergeProviderOptions } from './providerOptions.js';
import { loadProjectConfig, loadProjectConfigTraceState } from './project/projectConfig.js';
import { expandOptionalHomePath } from './pathExpansion.js';
import { resolveObservabilityConfig } from './observabilityConfig.js';
import { PROVIDER_OPTIONS_TRACE_PATHS, getPresentProviderOptionPaths, hasProviderOptionsPath, toProviderOptionsTracePath, } from './providerOptionsContract.js';
import { getCachedProjectConfig, getCachedResolvedValue, hasCachedResolvedValue, setCachedProjectConfig, setCachedResolvedValue, } from './resolutionCache.js';
export { invalidateResolvedConfigCache, invalidateAllResolvedConfigCache } from './resolutionCache.js';
/** Default values for project-local keys that need NonNullable guarantees */
const PROJECT_LOCAL_DEFAULTS = {
    minimalOutput: false,
    concurrency: 1,
    taskPollIntervalMs: 500,
    interactivePreviewSteps: 3,
    syncProjectLocalTaktOnRetry: true,
};
function loadProjectConfigCached(projectDir) {
    const cached = getCachedProjectConfig(projectDir);
    if (cached !== undefined) {
        return cached;
    }
    const loaded = loadProjectConfig(projectDir);
    setCachedProjectConfig(projectDir, loaded);
    return loaded;
}
const DEFAULT_RULE = {
    layers: ['local', 'global'],
};
const RESOLUTION_REGISTRY = {
    provider: {
        layers: ['local', 'workflow', 'global'],
        workflowValue: (workflowContext) => workflowContext?.provider,
    },
    model: {
        layers: ['local', 'workflow', 'global'],
        workflowValue: (workflowContext) => workflowContext?.model,
    },
    providerOptions: {
        layers: ['local', 'workflow', 'global'],
        workflowValue: (workflowContext) => workflowContext?.providerOptions,
    },
    allowGitHooks: { layers: ['local', 'global'] },
    allowGitFilters: { layers: ['local', 'global'] },
    vcsProvider: { layers: ['local', 'global'] },
    autoPr: { layers: ['local', 'global'] },
    draftPr: { layers: ['local', 'global'] },
    analytics: { layers: ['local', 'global'], mergeMode: 'analytics' },
    observability: { layers: ['local', 'global'], mergeMode: 'observability' },
    autoFetch: { layers: ['global'] },
    baseBranch: { layers: ['local', 'global'] },
    workflowOverrides: { layers: ['local', 'global'] },
};
function resolveAnalyticsMerged(project, global) {
    const localAnalytics = project.analytics;
    const globalAnalytics = global.analytics;
    const enabled = localAnalytics?.enabled ?? globalAnalytics?.enabled;
    const eventsPath = expandOptionalHomePath(localAnalytics?.eventsPath ?? globalAnalytics?.eventsPath);
    const retentionDays = localAnalytics?.retentionDays ?? globalAnalytics?.retentionDays;
    if (enabled === undefined && eventsPath === undefined && retentionDays === undefined) {
        return undefined;
    }
    return { enabled, eventsPath, retentionDays };
}
function resolveAnalyticsSource(project, global) {
    if (project.analytics !== undefined)
        return 'project';
    if (global.analytics !== undefined)
        return 'global';
    return 'default';
}
function resolveObservabilityMerged(project, global) {
    return resolveObservabilityConfig(project.observability, global.observability);
}
function resolveObservabilitySource(project, global) {
    if (project.observability !== undefined)
        return 'project';
    if (global.observability !== undefined)
        return 'global';
    return 'default';
}
function getLocalLayerValue(project, key) {
    return project[key];
}
function getGlobalLayerValue(global, key) {
    return global[key];
}
function resolveByRegistry(projectDir, key, project, global, options) {
    const rule = (RESOLUTION_REGISTRY[key] ?? DEFAULT_RULE);
    if (rule.mergeMode === 'analytics') {
        return {
            value: resolveAnalyticsMerged(project, global),
            source: resolveAnalyticsSource(project, global),
        };
    }
    if (rule.mergeMode === 'observability') {
        return {
            value: resolveObservabilityMerged(project, global),
            source: resolveObservabilitySource(project, global),
        };
    }
    for (const layer of rule.layers) {
        let value;
        if (layer === 'local') {
            value = getLocalLayerValue(project, key);
        }
        else if (layer === 'workflow') {
            value = rule.workflowValue?.(options?.workflowContext);
        }
        else {
            value = getGlobalLayerValue(global, key);
        }
        if (value !== undefined) {
            if (layer === 'local') {
                if (key === 'providerOptions') {
                    return { value, source: getProviderOptionsSource(loadProjectConfigTraceState(projectDir)) };
                }
                return { value, source: 'project' };
            }
            if (layer === 'workflow') {
                return { value, source: 'workflow' };
            }
            if (key === 'providerOptions') {
                return { value, source: getProviderOptionsSource(loadGlobalConfigTraceState()) };
            }
            return { value, source: 'global' };
        }
    }
    const fallbackDefaultValue = PROJECT_LOCAL_DEFAULTS[key];
    if (fallbackDefaultValue !== undefined) {
        return { value: fallbackDefaultValue, source: 'default' };
    }
    return { value: undefined, source: 'default' };
}
function resolveUncachedConfigValue(projectDir, key, options) {
    const project = loadProjectConfigCached(projectDir);
    const global = globalConfigModule.loadGlobalConfig();
    return resolveByRegistry(projectDir, key, project, global, options);
}
export function resolveConfigValueWithSource(projectDir, key, options) {
    const resolved = resolveUncachedConfigValue(projectDir, key, options);
    if (!options?.workflowContext) {
        setCachedResolvedValue(projectDir, key, resolved.value);
    }
    return resolved;
}
export function resolveConfigValue(projectDir, key, options) {
    if (!options?.workflowContext && hasCachedResolvedValue(projectDir, key)) {
        return getCachedResolvedValue(projectDir, key);
    }
    return resolveConfigValueWithSource(projectDir, key, options).value;
}
export function resolveConfigValues(projectDir, keys, options) {
    const result = {};
    for (const key of keys) {
        result[key] = resolveConfigValue(projectDir, key, options);
    }
    return result;
}
export function isDebugLoggingEnabled(projectDir, options) {
    const logging = resolveConfigValue(projectDir, 'logging', options);
    return logging?.debug === true || logging?.trace === true || logging?.level === 'debug';
}
function resolveProviderOptionsSourceFromValues(providerOptions, originResolver) {
    const paths = getPresentProviderOptionPaths(providerOptions);
    let sawLocal = false;
    let sawGlobal = false;
    for (const path of paths) {
        const origin = originResolver(path);
        if (origin === 'env' || origin === 'cli') {
            return 'env';
        }
        if (origin === 'local') {
            sawLocal = true;
            continue;
        }
        if (origin === 'global') {
            sawGlobal = true;
        }
    }
    if (sawLocal) {
        return 'project';
    }
    if (sawGlobal) {
        return 'global';
    }
    return 'default';
}
function getProviderOptionsSource(trace) {
    let sawLocal = false;
    let sawGlobal = false;
    for (const path of PROVIDER_OPTIONS_TRACE_PATHS) {
        const origin = trace.getOrigin(path);
        if (origin === 'env') {
            return 'env';
        }
        if (origin === 'cli') {
            return 'env';
        }
        if (origin === 'local') {
            sawLocal = true;
            continue;
        }
        if (origin === 'global') {
            sawGlobal = true;
        }
    }
    if (sawLocal) {
        return 'project';
    }
    if (sawGlobal) {
        return 'global';
    }
    return 'default';
}
export function resolveProviderOptionsWithTrace(projectDir) {
    const project = loadProjectConfigCached(projectDir);
    const global = globalConfigModule.loadGlobalConfig();
    const mergedProviderOptions = mergeProviderOptions(global.providerOptions, project.providerOptions);
    if (mergedProviderOptions !== undefined) {
        const projectTrace = loadProjectConfigTraceState(projectDir);
        const globalTrace = loadGlobalConfigTraceState();
        const originResolver = (path) => {
            if (hasProviderOptionsPath(project.providerOptions, path)) {
                return projectTrace.getOrigin(toProviderOptionsTracePath(path));
            }
            if (hasProviderOptionsPath(global.providerOptions, path)) {
                return globalTrace.getOrigin(toProviderOptionsTracePath(path));
            }
            if (project.providerOptions !== undefined) {
                return projectTrace.getOrigin(toProviderOptionsTracePath(path));
            }
            if (global.providerOptions !== undefined) {
                return globalTrace.getOrigin(toProviderOptionsTracePath(path));
            }
            return 'default';
        };
        return {
            value: mergedProviderOptions,
            source: resolveProviderOptionsSourceFromValues(mergedProviderOptions, originResolver),
            originResolver,
        };
    }
    return {
        value: undefined,
        source: 'default',
        originResolver: () => 'default',
    };
}
//# sourceMappingURL=resolveConfigValue.js.map