import { dispatchPolicyProviderTargets, } from './dispatch-ceiling-preset.js';
import { VALID_MANAGED_DISPATCH_POLICIES, } from './oat-config.js';
const MANAGED_POLICY_DESCRIPTIONS = {
    economy: 'Managed capped policy for lower-cost implementation and review dispatch.',
    balanced: 'Managed capped policy for normal implementation and review dispatch.',
    high: 'Managed capped policy for broad or higher-risk implementation and review dispatch.',
    frontier: 'Managed capped policy for highest-tier implementation and review dispatch.',
    uncapped: 'OAT still manages dispatch selection, but stores no maximum cap. The implementer can choose the preferred model/effort for the task. This is not host default behavior.',
};
const MANAGED_POLICY_LABELS = {
    economy: 'Economy',
    balanced: 'Balanced',
    high: 'High',
    frontier: 'Frontier',
    uncapped: 'Uncapped',
};
function isCappedManagedPolicy(policy) {
    return policy !== 'uncapped';
}
function managedChoice(policy) {
    if (isCappedManagedPolicy(policy)) {
        return {
            value: policy,
            label: MANAGED_POLICY_LABELS[policy],
            kind: 'managed-capped',
            runtimePolicy: true,
            description: MANAGED_POLICY_DESCRIPTIONS[policy],
            policy,
            providers: dispatchPolicyProviderTargets(policy),
        };
    }
    return {
        value: policy,
        label: MANAGED_POLICY_LABELS[policy],
        kind: 'managed-uncapped',
        runtimePolicy: true,
        description: MANAGED_POLICY_DESCRIPTIONS[policy],
        policy,
    };
}
export function getDispatchPolicyChoices() {
    return [
        ...VALID_MANAGED_DISPATCH_POLICIES.map(managedChoice),
        {
            value: 'inherit',
            label: 'Inherit Host Defaults',
            kind: 'inherit',
            runtimePolicy: true,
            description: 'OAT does not choose model or effort. Subagents use the current host/provider default behavior, such as parent session model, base Codex role defaults, or provider config.',
        },
        {
            value: 'leave-unresolved',
            label: 'Leave Unresolved',
            kind: 'unresolved',
            runtimePolicy: false,
            description: 'Planning records no policy as a planning/preflight deferral. Implementation preflight must block until a policy is configured or explicitly selected.',
        },
    ];
}
export function managedDispatchPolicyValueList(separator = ' | ') {
    return VALID_MANAGED_DISPATCH_POLICIES.join(separator);
}
export function dispatchPolicyModeDescription() {
    return [
        'Dispatch policy mode.',
        '"managed" means OAT selects model/effort from workflow.dispatchPolicy.policy.',
        '"inherit" leaves dispatch controls to host/provider defaults.',
        'Resolution: local > shared > user > default.',
    ].join(' ');
}
export function dispatchPolicyPolicyDescription() {
    return [
        'Managed dispatch policy.',
        'economy, balanced, high, and frontier are capped managed policies.',
        'uncapped keeps OAT-managed preferred selection without provider caps.',
        'inherit leaves dispatch controls to host/provider defaults through workflow.dispatchPolicy.mode.',
        'Setting this key writes workflow.dispatchPolicy.mode=managed.',
        'Resolution: local > shared > user > default.',
    ].join(' ');
}
function providerSummary(choice) {
    return choice.providers
        ? `Codex: ${choice.providers.codex}; Claude: ${choice.providers.claude}`
        : choice.kind === 'managed-uncapped'
            ? 'No stored maximum cap'
            : choice.kind === 'inherit'
                ? 'Host/provider defaults'
                : 'No runtime policy';
}
export function renderDispatchPolicyChoicesMarkdown(choices = getDispatchPolicyChoices()) {
    return [
        'Set the dispatch policy - how OAT should choose subagent model/effort controls.',
        '',
        ...choices.map((choice, index) => `${index + 1}. ${choice.label} - ${providerSummary(choice)}. ${choice.description}`),
    ].join('\n');
}
