import { getWorkflowStepKind } from '../../../core/models/workflow-step-kind.js';
import { applyQualityGateOverrides } from './qualityGateOverrides.js';
import { extractPersonaDisplayName, isResourcePath, resolvePersona, resolveRefList, resolveRefToContent, } from './resource-resolver.js';
import { mergeProviderOptions } from '../providerOptions.js';
import { normalizeConfigProviderReferenceDetailed } from '../providerReference.js';
import { validateWorkflowArpeggio, validateWorkflowMcpServers } from './workflowNormalizationPolicies.js';
import { normalizeRule } from './workflowRuleNormalizer.js';
import { normalizeArpeggio, normalizeOutputContracts, normalizeTeamLeader } from './workflowStepFeaturesNormalizer.js';
import { resolveStructuredOutput } from './workflowStructuredOutputResolver.js';
import { normalizeWorkflowEffects } from './workflowSystemStepNormalizer.js';
import { parseAiConditionExpression } from '../../../core/models/workflow-condition-expression.js';
export function normalizeProviderReference(provider, model, providerOptions) {
    return normalizeConfigProviderReferenceDetailed(provider, model, providerOptions);
}
function normalizePromotionEntry(entry) {
    const normalizedProvider = normalizeProviderReference(entry.provider, entry.model, entry.provider_options);
    const aiExpression = entry.condition !== undefined
        ? parseAiConditionExpression(entry.condition)
        : undefined;
    return {
        at: entry.at,
        condition: entry.condition,
        aiConditionText: aiExpression?.text,
        provider: normalizedProvider.provider,
        providerSpecified: normalizedProvider.providerSpecified,
        model: normalizedProvider.model,
        providerOptions: normalizedProvider.providerOptions,
    };
}
function normalizePromotionEntries(entries) {
    return entries?.map(normalizePromotionEntry);
}
export function normalizeStepFromRaw(step, workflowDir, sections, workflowSchemas, inheritedProvider, inheritedModel, inheritedProviderOptions, inheritedAllowGitCommit, context, projectOverrides, globalOverrides, workflowArpeggioPolicy, workflowMcpServersPolicy) {
    const rules = step.rules?.map(normalizeRule);
    const kind = getWorkflowStepKind(step);
    const isSystemStep = kind === 'system';
    const isWorkflowCallStep = kind === 'workflow_call';
    const rawPersona = step.persona;
    if (rawPersona !== undefined && rawPersona.trim().length === 0) {
        throw new Error(`Step "${step.name}" has an empty persona value`);
    }
    const { personaSpec, personaPath } = isSystemStep || isWorkflowCallStep
        ? { personaSpec: undefined, personaPath: undefined }
        : resolvePersona(rawPersona, sections, workflowDir, context);
    const displayNameRaw = step.persona_name;
    if (displayNameRaw !== undefined && displayNameRaw.trim().length === 0) {
        throw new Error(`Step "${step.name}" has an empty persona_name value`);
    }
    const derivedPersonaName = personaSpec ? extractPersonaDisplayName(personaSpec) : undefined;
    const resolvedPersonaDisplayName = isSystemStep || isWorkflowCallStep
        ? step.name
        : displayNameRaw || derivedPersonaName || step.name;
    const normalizedRawPersona = rawPersona?.trim();
    const personaOverrideKey = normalizedRawPersona
        ? (isResourcePath(normalizedRawPersona) ? extractPersonaDisplayName(normalizedRawPersona) : normalizedRawPersona)
        : undefined;
    const policyContents = isSystemStep || isWorkflowCallStep
        ? undefined
        : resolveRefList(step.policy, sections.resolvedPoliciesWithSource ?? sections.resolvedPolicies, workflowDir, 'policies', context);
    const knowledgeContents = isSystemStep || isWorkflowCallStep
        ? undefined
        : resolveRefList(step.knowledge, sections.resolvedKnowledgeWithSource ?? sections.resolvedKnowledge, workflowDir, 'knowledge', context);
    const normalizedProvider = normalizeProviderReference(step.provider, step.model, step.provider_options);
    const promotion = normalizePromotionEntries(step.promotion);
    const normalizedOverrides = step.overrides
        ? normalizeProviderReference(step.overrides.provider, step.overrides.model, step.overrides.provider_options)
        : undefined;
    const instruction = isSystemStep || isWorkflowCallStep
        ? undefined
        : step.instruction
            ? resolveRefToContent(step.instruction, sections.resolvedInstructionsWithSource ?? sections.resolvedInstructions, workflowDir, 'instructions', context)
            : undefined;
    validateWorkflowArpeggio(step.name, step.arpeggio, workflowArpeggioPolicy);
    validateWorkflowMcpServers(step.name, step.mcp_servers, workflowMcpServersPolicy);
    if (isWorkflowCallStep) {
        const normalizedStep = {
            name: step.name,
            description: step.description,
            kind: 'workflow_call',
            call: step.call,
            overrides: normalizedOverrides
                ? {
                    provider: normalizedOverrides.provider,
                    model: normalizedOverrides.model,
                    providerOptions: normalizedOverrides.providerOptions,
                }
                : undefined,
            args: step.args,
            personaDisplayName: resolvedPersonaDisplayName,
            instruction: '',
            rules,
        };
        return normalizedStep;
    }
    if (isSystemStep) {
        const normalizedStep = {
            name: step.name,
            description: step.description,
            kind: 'system',
            session: step.session,
            personaDisplayName: resolvedPersonaDisplayName,
            instruction: '',
            delayBeforeMs: step.delay_before_ms,
            systemInputs: step.system_inputs,
            effects: normalizeWorkflowEffects(step.effects),
            rules,
            passPreviousResponse: step.pass_previous_response ?? true,
        };
        return normalizedStep;
    }
    const qualityGates = applyQualityGateOverrides(step.name, step.quality_gates, step.edit, personaOverrideKey, projectOverrides, globalOverrides);
    const normalizedStep = {
        name: step.name,
        description: step.description,
        kind: 'agent',
        persona: personaSpec,
        session: step.session,
        personaDisplayName: resolvedPersonaDisplayName,
        personaPath,
        mcpServers: step.mcp_servers,
        provider: normalizedProvider.provider ?? inheritedProvider,
        model: normalizedProvider.model ?? (normalizedProvider.providerSpecified ? undefined : inheritedModel),
        promotion,
        requiredPermissionMode: step.required_permission_mode,
        providerOptions: mergeProviderOptions(inheritedProviderOptions, normalizedProvider.providerOptions),
        edit: step.edit,
        allowGitCommit: step.allow_git_commit ?? inheritedAllowGitCommit ?? false,
        instruction: instruction || '{task}',
        delayBeforeMs: step.delay_before_ms,
        structuredOutput: resolveStructuredOutput(step, workflowSchemas, {
            projectDir: context?.projectDir ?? workflowDir,
        }),
        rules,
        outputContracts: normalizeOutputContracts(step.output_contracts, workflowDir, sections.resolvedReportFormatsWithSource ?? sections.resolvedReportFormats, context),
        qualityGates,
        passPreviousResponse: step.pass_previous_response ?? true,
        policyContents,
        knowledgeContents,
    };
    if (step.parallel && step.parallel.length > 0) {
        normalizedStep.parallel = step.parallel.map((sub) => normalizeStepFromRaw(sub, workflowDir, sections, workflowSchemas, normalizedStep.provider, normalizedStep.model, normalizedStep.providerOptions, normalizedStep.allowGitCommit, context, projectOverrides, globalOverrides, workflowArpeggioPolicy, workflowMcpServersPolicy));
        if (step.concurrency != null) {
            normalizedStep.concurrency = step.concurrency;
        }
    }
    const arpeggio = normalizeArpeggio(step.arpeggio, workflowDir);
    if (arpeggio)
        normalizedStep.arpeggio = arpeggio;
    const teamLeader = normalizeTeamLeader(step.team_leader, workflowDir, sections, context);
    if (teamLeader)
        normalizedStep.teamLeader = teamLeader;
    return normalizedStep;
}
//# sourceMappingURL=workflowStepNormalizer.js.map