/**
 * Workflow resolution.
 */
import { existsSync } from 'node:fs';
import { homedir } from 'node:os';
import { isAbsolute, join, resolve } from 'node:path';
import { isScopeRef, parseScopeRef } from 'faceted-prompting';
import { validateWorkflowCallContracts as validateWorkflowCallContractsImpl } from './workflowCallContractValidator.js';
import { buildWorkflowDiscoveryConfig, loadValidatedWorkflowDiscoveryEntry } from './workflowDiscoveryLoader.js';
import { findWorkflowInLookupDirs, getBuiltinWorkflowPath, getNamedWorkflowLookupDirs, getWorkflowDirs, listBuiltinWorkflowNames as listBuiltinWorkflowNamesImpl, resolveWorkflowFile, } from './workflowLookupDirectories.js';
import { loadWorkflowFileWithResolutionOptions } from './workflowResolvedLoader.js';
import { getRepertoireDir } from '../paths.js';
import { collectValidatedWorkflowEntries, iterateWorkflowDir, listRepertoireWorkflowEntries, loadAllWorkflowsWithSourcesFromDirs, } from './workflowDiscovery.js';
export { getWorkflowDescription } from './workflowPreview.js';
function resolvePath(pathInput, basePath) {
    if (pathInput.startsWith('~')) {
        return resolve(homedir(), pathInput.slice(1).replace(/^\//, ''));
    }
    if (isAbsolute(pathInput)) {
        return pathInput;
    }
    return resolve(basePath, pathInput);
}
function loadWorkflowFromLookupDirs(name, lookupDirs, projectCwd, lookupCwd, callableArgs, parentTrustInfo) {
    const match = findWorkflowInLookupDirs(name, lookupDirs);
    if (!match) {
        return null;
    }
    return loadWorkflowFileWithResolutionOptions(match.filePath, {
        projectCwd,
        lookupCwd,
        source: match.source,
        callableArgs,
        parentTrustInfo,
    });
}
export function listBuiltinWorkflowNames(cwd, options) {
    return listBuiltinWorkflowNamesImpl(cwd, options);
}
export function getBuiltinWorkflow(name, projectCwd) {
    const yamlPath = getBuiltinWorkflowPath(name, projectCwd);
    if (!yamlPath) {
        return null;
    }
    const workflow = loadWorkflowFileWithResolutionOptions(yamlPath, {
        projectCwd,
        lookupCwd: projectCwd,
        source: 'builtin',
    });
    return finalizeLoadedWorkflow(workflow, projectCwd, projectCwd);
}
function loadWorkflowFromPath(filePath, basePath, projectCwd, lookupCwd, callableArgs, parentTrustInfo) {
    const resolvedPath = resolvePath(filePath, basePath);
    return loadWorkflowFromResolvedPath(resolvedPath, projectCwd, lookupCwd, callableArgs, parentTrustInfo);
}
function loadWorkflowFromResolvedPath(resolvedPath, projectCwd, lookupCwd = projectCwd, callableArgs, parentTrustInfo) {
    if (!existsSync(resolvedPath)) {
        return null;
    }
    return loadWorkflowFileWithResolutionOptions(resolvedPath, {
        projectCwd,
        lookupCwd,
        callableArgs,
        parentTrustInfo,
    });
}
function finalizeLoadedWorkflow(workflow, projectCwd, lookupCwd, skipWorkflowCallContractValidation = false, allowPathBasedCalls = true) {
    if (!workflow || skipWorkflowCallContractValidation) {
        return workflow;
    }
    validateWorkflowCallContracts(workflow, projectCwd, lookupCwd, { allowPathBasedCalls });
    return workflow;
}
function loadWorkflowForDiscovery(entry, cwd) {
    return loadWorkflowFileWithResolutionOptions(entry.path, {
        projectCwd: cwd,
        lookupCwd: cwd,
        source: entry.source,
        loadMode: 'discovery',
    });
}
function loadWorkflowForRuntime(entry, cwd) {
    return loadWorkflowFileWithResolutionOptions(entry.path, {
        projectCwd: cwd,
        lookupCwd: cwd,
        source: entry.source,
    });
}
function validateLoadedWorkflowEntryContracts(workflow, cwd, allowPathBasedCalls) {
    validateWorkflowCallContracts(workflow, cwd, cwd, { allowPathBasedCalls });
}
function loadValidatedWorkflowEntry(entry, cwd) {
    return loadValidatedWorkflowDiscoveryEntry(entry, cwd, {
        loadWorkflowForDiscovery,
        validateWorkflowCallContracts: (workflow, projectCwd, options) => {
            validateLoadedWorkflowEntryContracts(workflow, options?.lookupCwd ?? projectCwd, options?.allowPathBasedCalls ?? true);
        },
    });
}
function loadValidatedWorkflowConfigEntry(entry, cwd) {
    const workflow = loadWorkflowForRuntime(entry, cwd);
    validateLoadedWorkflowEntryContracts(workflow, cwd, true);
    return workflow;
}
function loadValidatedStandaloneWorkflowEntry(entry, cwd) {
    return buildWorkflowDiscoveryConfig(loadValidatedWorkflowConfigEntry(entry, cwd));
}
export function loadWorkflow(name, projectCwd) {
    const workflow = loadWorkflowFromLookupDirs(name, getNamedWorkflowLookupDirs(projectCwd), projectCwd, projectCwd);
    return finalizeLoadedWorkflow(workflow, projectCwd, projectCwd);
}
export function isWorkflowPath(identifier) {
    return (identifier.startsWith('/') ||
        identifier.startsWith('~') ||
        identifier.startsWith('./') ||
        identifier.startsWith('../') ||
        identifier.endsWith('.yaml') ||
        identifier.endsWith('.yml'));
}
function loadRepertoireWorkflowByRef(identifier, projectCwd, callableArgs, parentTrustInfo) {
    const scopeRef = parseScopeRef(identifier);
    const workflowsDir = join(getRepertoireDir(), `@${scopeRef.owner}`, scopeRef.repo, 'workflows');
    const filePath = resolveWorkflowFile(workflowsDir, scopeRef.name);
    return filePath
        ? loadWorkflowFileWithResolutionOptions(filePath, {
            projectCwd,
            lookupCwd: projectCwd,
            source: 'repertoire',
            callableArgs,
            parentTrustInfo,
        })
        : null;
}
export function validateWorkflowCallContracts(workflow, projectCwd, lookupCwd = projectCwd, options) {
    validateWorkflowCallContractsImpl(workflow, projectCwd, {
        isWorkflowPath,
        loadWorkflowByIdentifierForWorkflowCall,
    }, {
        lookupCwd,
        allowPathBasedCalls: options?.allowPathBasedCalls,
    });
}
function loadWorkflowByIdentifierInternal(identifier, projectCwd, options) {
    const lookupCwd = options?.lookupCwd ?? projectCwd;
    const basePath = options?.basePath ?? lookupCwd;
    const workflow = isScopeRef(identifier)
        ? loadRepertoireWorkflowByRef(identifier, projectCwd, options?.callableArgs, options?.parentTrustInfo)
        : isWorkflowPath(identifier)
            ? loadWorkflowFromPath(identifier, basePath, projectCwd, lookupCwd, options?.callableArgs, options?.parentTrustInfo)
            : loadWorkflowFromLookupDirs(identifier, getNamedWorkflowLookupDirs(projectCwd), projectCwd, lookupCwd, options?.callableArgs, options?.parentTrustInfo);
    return finalizeLoadedWorkflow(workflow, projectCwd, lookupCwd, options?.skipWorkflowCallContractValidation === true);
}
export function loadWorkflowByIdentifier(identifier, projectCwd, options) {
    return loadWorkflowByIdentifierInternal(identifier, projectCwd, options);
}
export function loadWorkflowByIdentifierForWorkflowCall(identifier, projectCwd, options) {
    return loadWorkflowByIdentifierInternal(identifier, projectCwd, options);
}
export function loadAllWorkflowsWithSources(cwd, options) {
    return loadAllWorkflowsWithSourcesFromDirs(cwd, getWorkflowDirs(cwd), options, loadValidatedWorkflowConfigEntry, true);
}
export function loadAllWorkflowDiscoveryWithSources(cwd, options) {
    return loadAllWorkflowsWithSourcesFromDirs(cwd, getWorkflowDirs(cwd), options, loadValidatedWorkflowEntry);
}
export function loadAllStandaloneWorkflowsWithSources(cwd, options) {
    return loadAllWorkflowsWithSourcesFromDirs(cwd, getWorkflowDirs(cwd), options, loadValidatedStandaloneWorkflowEntry);
}
export function listWorkflowEntries(cwd, options) {
    const dirs = getWorkflowDirs(cwd);
    const entries = dirs.flatMap(({ dir, source, disabled }) => Array.from(iterateWorkflowDir(dir, source, disabled)));
    entries.push(...listRepertoireWorkflowEntries());
    return collectValidatedWorkflowEntries(entries, cwd, options, loadValidatedWorkflowEntry).map(({ entry }) => entry);
}
export function listStandaloneWorkflowEntries(cwd, options) {
    const dirs = getWorkflowDirs(cwd);
    const entries = dirs.flatMap(({ dir, source, disabled }) => Array.from(iterateWorkflowDir(dir, source, disabled)));
    entries.push(...listRepertoireWorkflowEntries());
    return collectValidatedWorkflowEntries(entries, cwd, options, loadValidatedStandaloneWorkflowEntry)
        .map(({ entry }) => entry);
}
export function loadAllWorkflows(cwd, options) {
    return new Map(Array.from(loadAllWorkflowsWithSources(cwd, options).entries()).map(([name, entry]) => [name, entry.config]));
}
export function loadAllWorkflowDiscovery(cwd, options) {
    return new Map(Array.from(loadAllWorkflowDiscoveryWithSources(cwd, options).entries()).map(([name, entry]) => [name, entry.config]));
}
export function loadAllStandaloneWorkflows(cwd, options) {
    return new Map(Array.from(loadAllStandaloneWorkflowsWithSources(cwd, options).entries()).map(([name, entry]) => [name, entry.config]));
}
export function listWorkflows(cwd, options) {
    return listWorkflowEntries(cwd, options).map((entry) => entry.name).sort();
}
//# sourceMappingURL=workflowResolver.js.map