"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.normalizeCommandCapabilityWithTokens = normalizeCommandCapabilityWithTokens;
exports.normalizeCommandCapabilityRegistryWith = normalizeCommandCapabilityRegistryWith;
exports.findCommandCapabilityInRegistry = findCommandCapabilityInRegistry;
exports.createNoWriteBoundaryEvidenceWithOperations = createNoWriteBoundaryEvidenceWithOperations;
exports.createNoWriteRecommendationWithOperations = createNoWriteRecommendationWithOperations;
exports.createNoWriteFindingEvidenceDetailsWithOperations = createNoWriteFindingEvidenceDetailsWithOperations;
exports.classifySourceSpecLifecycleIntentWithOperations = classifySourceSpecLifecycleIntentWithOperations;
exports.createSourceSpecLifecycleGateEvidenceDetailsWithOperations = createSourceSpecLifecycleGateEvidenceDetailsWithOperations;
const cli_constants_1 = require("../config/cli-constants");
const NON_WRITING_CAPABILITIES = new Set([
    'read',
    'validation',
    'review',
    'navigation',
    'list',
    'inspection',
]);
const WRITE_CAPABLE_CAPABILITIES = new Set([
    'scaffold',
    'update',
    'build',
    'sync',
    'migration',
    'install',
    'materialize',
    'release',
    'cleanup',
]);
function normalizeCommandCapabilityWithTokens(registration, availabilityTokens, capabilityTokens) {
    const command = normalizeRequiredText(registration.command, 'command');
    const summary = normalizeRequiredText(registration.summary, `${command} summary`);
    const availability = registration.availability ?? 'callable';
    if (!availabilityTokens.includes(availability)) {
        throw new Error(`Command '${command}' uses unsupported availability '${availability}'.`);
    }
    if (!capabilityTokens.includes(registration.capability)) {
        throw new Error(`Command '${command}' uses unsupported capability '${registration.capability}'.`);
    }
    if (NON_WRITING_CAPABILITIES.has(registration.capability)) {
        if (registration.writeCapable) {
            throw new Error(`Command '${command}' uses non-writing capability '${registration.capability}' but is marked writeCapable.`);
        }
        return Object.freeze({
            command,
            availability,
            capability: registration.capability,
            primaryCapability: registration.capability,
            summary,
            writeCapable: false,
            artifactFamily: registration.artifactFamily ?? 'planning',
            destinationPosture: registration.destinationPosture ?? 'none',
            targetPathPosture: registration.targetPathPosture ?? 'none',
            coordinationScope: registration.coordinationScope ?? 'none',
            mutationPosture: 'non-writing',
            noWriteBoundary: normalizeRequiredText(registration.noWriteBoundary, `${command} no-write boundary`),
        });
    }
    if (!WRITE_CAPABLE_CAPABILITIES.has(registration.capability)) {
        throw new Error(`Command '${command}' uses unclassified capability '${registration.capability}'.`);
    }
    if (!registration.writeCapable) {
        throw new Error(`Command '${command}' uses write-capable capability '${registration.capability}' but writeCapable is false.`);
    }
    return Object.freeze({
        command,
        availability,
        capability: registration.capability,
        primaryCapability: registration.capability,
        summary,
        writeCapable: true,
        artifactFamily: requireField(registration.artifactFamily, command, 'artifactFamily'),
        destinationPosture: requireField(registration.destinationPosture, command, 'destinationPosture'),
        targetPathPosture: normalizeRequiredText(registration.targetPathPosture, `${command} targetPathPosture`),
        coordinationScope: requireField(registration.coordinationScope, command, 'coordinationScope'),
        mutationPosture: requireField(registration.mutationPosture, command, 'mutationPosture'),
        noWriteBoundary: registration.noWriteBoundary ??
            'Write-capable command; mutation is limited to the declared artifact family, destination posture, target-path posture, and coordination scope.',
    });
}
function normalizeCommandCapabilityRegistryWith(registrations, normalize) {
    const seen = new Set();
    return Object.freeze(registrations.map((registration) => {
        const normalized = normalize(registration);
        if (seen.has(normalized.command)) {
            throw new Error(`Duplicate command capability registration for '${normalized.command}'.`);
        }
        seen.add(normalized.command);
        return normalized;
    }));
}
function findCommandCapabilityInRegistry(registry, command) {
    return registry.find((entry) => entry.command === command) ?? null;
}
function createNoWriteBoundaryEvidenceWithOperations(commandOrCapability, options, operations) {
    const capability = typeof commandOrCapability === 'string'
        ? operations.findCommandCapability(options.registry ?? operations.defaultRegistry, commandOrCapability)
        : commandOrCapability;
    if (capability === null) {
        throw new Error(`No command capability registration exists for '${commandOrCapability}'.`);
    }
    if (capability.writeCapable) {
        throw new Error(`Command '${capability.command}' is write-capable and cannot be represented as read-only no-write evidence.`);
    }
    const severity = options.severity ?? 'informational';
    if (!operations.noWriteEvidenceSeverities.includes(severity)) {
        throw new Error(`Unsupported no-write evidence severity '${severity}'.`);
    }
    return Object.freeze({
        command: capability.command,
        capability: capability.capability,
        primaryCapability: capability.primaryCapability,
        writeCapable: false,
        artifactFamily: capability.artifactFamily,
        coordinationScope: 'none',
        mutationPosture: 'non-writing',
        noWriteBoundary: capability.noWriteBoundary,
        noWriteReason: options.noWriteReason ?? 'The command is a read-only evidence surface.',
        evidenceOnly: true,
        severity,
        ...(options.recommendedCommand === undefined
            ? {}
            : {
                recommendation: createNoWriteRecommendationWithOperations(options.recommendedCommand, {
                    recommendationLabel: options.recommendationLabel,
                    recommendationBoundary: options.recommendationBoundary,
                    registry: options.registry,
                }, operations),
            }),
    });
}
function createNoWriteRecommendationWithOperations(command, options, operations) {
    const normalizedCommand = normalizeRequiredText(command, 'recommended follow-up command');
    const recommendedCapability = operations.findCommandCapability(options.registry ?? operations.defaultRegistry, normalizedCommand);
    return Object.freeze({
        command: normalizedCommand,
        label: options.recommendationLabel ?? 'Separate follow-up command',
        writeCapable: recommendedCapability?.writeCapable ?? true,
        ...(recommendedCapability === null
            ? {}
            : {
                capability: recommendedCapability.capability,
                artifactFamily: recommendedCapability.artifactFamily,
                mutationPosture: recommendedCapability.mutationPosture,
                coordinationScope: recommendedCapability.coordinationScope,
            }),
        followUpOnly: true,
        boundary: options.recommendationBoundary ??
            'Recommended command is a separate follow-up action; the current read-only command did not run it.',
    });
}
function createNoWriteFindingEvidenceDetailsWithOperations(commandOrCapability, options, operations) {
    const evidence = createNoWriteBoundaryEvidenceWithOperations(commandOrCapability, options, operations);
    return Object.freeze({
        command: evidence.command,
        ruleFamily: 'command-capability',
        evidenceSource: 'command-capability-registry',
        capability: evidence.capability,
        primaryCapability: evidence.primaryCapability,
        writeCapable: evidence.writeCapable,
        artifactFamily: evidence.artifactFamily,
        coordinationScope: evidence.coordinationScope,
        mutationPosture: evidence.mutationPosture,
        noWriteBoundary: evidence.noWriteBoundary,
        noWriteReason: evidence.noWriteReason,
        reason: evidence.noWriteReason,
        evidenceOnly: evidence.evidenceOnly,
        noWriteSeverity: evidence.severity,
        ...(evidence.recommendation === undefined
            ? {}
            : {
                nextAction: evidence.recommendation.command,
                recommendedCommand: evidence.recommendation.command,
                recommendationLabel: evidence.recommendation.label,
                recommendationWriteCapable: evidence.recommendation.writeCapable,
                recommendationCapability: evidence.recommendation.capability,
                recommendationArtifactFamily: evidence.recommendation.artifactFamily,
                recommendationMutationPosture: evidence.recommendation.mutationPosture,
                recommendationCoordinationScope: evidence.recommendation.coordinationScope,
                recommendationFollowUpOnly: evidence.recommendation.followUpOnly,
                recommendationBoundary: evidence.recommendation.boundary,
            }),
    });
}
function classifySourceSpecLifecycleIntentWithOperations(input, selectedSourceSpecSurface, operations) {
    const normalizedInput = normalizeIntentInput(input);
    const planningAdvancementPhrase = findExplicitIntentPhrase(normalizedInput, operations.planningAdvancementIntentPhrases);
    if (planningAdvancementPhrase !== null) {
        return createSourceSpecIntentClassification({
            intent: 'planning-advancement',
            matchedPhrase: planningAdvancementPhrase,
            selectedSourceSpecSurface: selectedSourceSpecSurface ?? cli_constants_1.CLI_DEFAULT_SOURCE_SPEC_SURFACE,
            noDownstreamPlanningWrite: false,
            planningRecoveryCommand: cli_constants_1.CLI_SOURCE_SPEC_PLANNING_RECOVERY_COMMAND,
            planningRecoveryWorkflow: cli_constants_1.CLI_SOURCE_SPEC_PLANNING_RECOVERY_WORKFLOW,
            reason: 'The request explicitly selects a planning-advancement lifecycle action.',
        });
    }
    const sourceSpecOnlyPhrase = findExplicitIntentPhrase(normalizedInput, operations.sourceSpecOnlyIntentPhrases);
    if (sourceSpecOnlyPhrase !== null) {
        return createSourceSpecIntentClassification({
            intent: 'source-spec-only',
            matchedPhrase: sourceSpecOnlyPhrase,
            selectedSourceSpecSurface: selectedSourceSpecSurface ?? cli_constants_1.CLI_DEFAULT_SOURCE_SPEC_SURFACE,
            noDownstreamPlanningWrite: true,
            planningRecoveryCommand: cli_constants_1.CLI_SOURCE_SPEC_PLANNING_RECOVERY_COMMAND,
            planningRecoveryWorkflow: cli_constants_1.CLI_SOURCE_SPEC_PLANNING_RECOVERY_WORKFLOW,
            reason: 'Source-spec authoring and revision stop at the selected source-spec surface unless planning advancement is explicit.',
        });
    }
    const reviewPhrase = findExplicitIntentPhrase(normalizedInput, operations.sourceSpecReviewRefinementIntentPhrases);
    if (reviewPhrase !== null) {
        return createSourceSpecIntentClassification({
            intent: 'review-or-refinement',
            matchedPhrase: reviewPhrase,
            selectedSourceSpecSurface: selectedSourceSpecSurface ?? cli_constants_1.CLI_DEFAULT_SOURCE_SPEC_SURFACE,
            noDownstreamPlanningWrite: true,
            planningRecoveryCommand: cli_constants_1.CLI_SOURCE_SPEC_PLANNING_RECOVERY_COMMAND,
            planningRecoveryWorkflow: cli_constants_1.CLI_SOURCE_SPEC_PLANNING_RECOVERY_WORKFLOW,
            reason: 'Source-spec review, hardening, second-pass, improvement, navigation, and completeness discussions are evidence-only or selected-spec-only by default.',
        });
    }
    return createSourceSpecIntentClassification({
        intent: 'unclassified',
        matchedPhrase: null,
        selectedSourceSpecSurface: selectedSourceSpecSurface ?? cli_constants_1.CLI_DEFAULT_SOURCE_SPEC_SURFACE,
        noDownstreamPlanningWrite: true,
        planningRecoveryCommand: cli_constants_1.CLI_SOURCE_SPEC_PLANNING_RECOVERY_COMMAND,
        planningRecoveryWorkflow: cli_constants_1.CLI_SOURCE_SPEC_PLANNING_RECOVERY_WORKFLOW,
        reason: 'No explicit planning-advancement lifecycle phrase was detected.',
    });
}
function createSourceSpecLifecycleGateEvidenceDetailsWithOperations(input, options, operations) {
    const classification = classifySourceSpecLifecycleIntentWithOperations(input, options.selectedSourceSpecSurface, operations);
    const noWriteEvidence = createNoWriteFindingEvidenceDetailsWithOperations(options.command ?? 'spec', {
        severity: options.severity ?? 'informational',
        noWriteReason: classification.reason,
        recommendedCommand: classification.planningRecoveryCommand ?? undefined,
        recommendationLabel: 'Advance into planning explicitly',
        recommendationBoundary: 'Planning advancement is a separate lifecycle action; the current source-spec flow did not create downstream planning artifacts.',
    }, operations);
    return Object.freeze({
        ...noWriteEvidence,
        sourceSpecIntent: classification.intent,
        matchedSourceSpecPhrase: classification.matchedPhrase,
        selectedSourceSpecSurface: classification.selectedSourceSpecSurface,
        noDownstreamPlanningWrite: classification.noDownstreamPlanningWrite,
        planningRecoveryCommand: classification.planningRecoveryCommand,
        planningRecoveryWorkflow: classification.planningRecoveryWorkflow,
        sourceSpecLifecycleReason: classification.reason,
    });
}
function normalizeRequiredText(value, field) {
    const normalized = value?.trim();
    if (normalized === undefined || normalized.length === 0) {
        throw new Error(`Missing command capability ${field}.`);
    }
    return normalized;
}
function normalizeIntentInput(input) {
    return input.toLowerCase().replace(/[-_]+/g, ' ').replace(/\s+/g, ' ').trim();
}
function findExplicitIntentPhrase(input, phrases) {
    for (const phrase of phrases) {
        const normalizedPhrase = normalizeIntentInput(phrase);
        const phrasePattern = new RegExp(`(^| )${escapeRegExp(normalizedPhrase)}($| )`);
        if (phrasePattern.test(input))
            return phrase;
    }
    return null;
}
function escapeRegExp(value) {
    return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}
function createSourceSpecIntentClassification(classification) {
    return Object.freeze({
        ...classification,
        selectedSourceSpecSurface: normalizeOptionalIntentSurface(classification.selectedSourceSpecSurface),
    });
}
function normalizeOptionalIntentSurface(value) {
    const normalized = value?.trim();
    return normalized === undefined || normalized.length === 0
        ? cli_constants_1.CLI_DEFAULT_SOURCE_SPEC_SURFACE
        : normalized;
}
function requireField(value, command, field) {
    if (value === undefined || value.trim().length === 0) {
        throw new Error(`Command '${command}' is missing required write-capable posture field '${field}'.`);
    }
    return value;
}
