"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createWorkSelectCommand = createWorkSelectCommand;
exports.createWorkCurrentCommand = createWorkCurrentCommand;
exports.createWorkNextCommand = createWorkNextCommand;
exports.createWorkClearCommand = createWorkClearCommand;
exports.createWorkCleanupCommand = createWorkCleanupCommand;
const errors_1 = require("../../../lib/errors");
const output_1 = require("../../../lib/output");
const planning_navigation_1 = require("../../../lib/planning/planning-navigation");
const work_selection_1 = require("../../../lib/work-selection");
const runtime_contract_1 = require("../../../lib/runtime/runtime-contract");
async function createWorkSelectCommand() {
    const { Command } = await import('commander');
    return new Command('select')
        .description('Persist one explicit planning artifact in a user-local named work session.')
        .requiredOption('--artifact <path>', 'Repository-relative planning artifact to select.')
        .option('--session <name>', 'Named local session. Defaults to default.')
        .option('--intent <text>', 'Bounded provenance for why the selection was established.')
        .option('--if-match <token>', 'Opaque token from work current; required to replace existing session state.')
        .action((options, commandInstance) => {
        const format = requireFormat(commandInstance);
        const repositoryContext = resolveRepositoryContext(commandInstance);
        const result = (0, work_selection_1.selectWorkArtifact)({
            repositoryRoot: repositoryContext.root,
            artifactPath: options.artifact,
            session: options.session,
            intent: options.intent,
            ifMatch: options.ifMatch,
        });
        (0, output_1.emitSuccess)({
            command: 'work select',
            format,
            data: { ...result, writeApplied: true, stateSurface: 'user-local work selection' },
            text: [
                'Work selection updated',
                `Session: ${result.session}`,
                `Artifact: ${result.selection?.artifactPath ?? '(none)'}`,
                `Revision: ${result.storeRevision}`,
                (0, output_1.renderTerminalBoundary)({
                    kind: 'write-applied',
                    target: result.session,
                    stateSurface: 'user-local work selection',
                }),
            ].join('\n'),
        });
    });
}
async function createWorkCurrentCommand() {
    const { Command } = await import('commander');
    return new Command('current')
        .description('Inspect current named work selection and freshness without writing state.')
        .option('--session <name>', 'Named local session. Defaults to default.')
        .action((options, commandInstance) => {
        const format = requireFormat(commandInstance);
        const repositoryContext = resolveRepositoryContext(commandInstance);
        const result = (0, work_selection_1.inspectWorkSelection)({ repositoryRoot: repositoryContext.root, ...options });
        (0, output_1.emitSuccess)({
            command: 'work current',
            format,
            data: {
                ...result,
                readOnly: true,
                noWriteBoundary: 'Current inspection does not create, refresh, or clear selection state.',
            },
            text: [
                'Current work selection',
                `Session: ${result.session}`,
                `State: ${result.state}`,
                `Artifact: ${result.selection?.artifactPath ?? '(none)'}`,
                `Stale reason: ${result.staleReason ?? '(none)'}`,
                (0, output_1.renderTerminalBoundary)({ kind: 'read-only' }),
            ].join('\n'),
        });
    });
}
async function createWorkNextCommand() {
    const { Command } = await import('commander');
    return new Command('next')
        .description('Resolve explicit or stored work selection and report its next action without writing state.')
        .option('--artifact <path>', 'Explicit repository-relative planning artifact for this invocation.')
        .option('--session <name>', 'Named local session. Defaults to default.')
        .action((options, commandInstance) => {
        const format = requireFormat(commandInstance);
        const repositoryContext = resolveRepositoryContext(commandInstance);
        const resolution = (0, work_selection_1.resolveWorkSelection)({
            repositoryRoot: repositoryContext.root,
            explicitArtifactPath: options.artifact,
            session: options.session,
        });
        assertResolvedSelection(resolution);
        const nextAction = (0, planning_navigation_1.suggestPlanningNextAction)({
            repositoryRoot: repositoryContext.root,
            artifactPath: resolution.artifactPath,
        });
        const { workEvidence: _duplicateWorkEvidence, ...nextActionProjection } = nextAction;
        (0, output_1.emitSuccess)({
            command: 'work next',
            format,
            data: {
                resolution,
                nextAction: nextActionProjection,
                readOnly: true,
                noWriteBoundary: 'Next-action resolution does not create, refresh, replace, or clear selection state.',
            },
            text: [
                'Selected work next action',
                `Selection source: ${resolution.source}`,
                `Artifact: ${resolution.artifactPath}`,
                `Collaboration mode: ${nextAction.workEvidence?.effectiveAgentMode ?? '(not applicable)'}`,
                `Evidence profile: ${nextAction.workEvidence?.evidenceProfile ?? '(not applicable)'}`,
                `Derived action: ${nextAction.nextAction?.nextAction ?? '(not applicable)'}`,
                `Reason code: ${nextAction.nextAction?.reasonCode ?? '(not applicable)'}`,
                `Recommendation: ${nextAction.recommendation}`,
                `Command: ${nextAction.command ?? '(workflow-guided step)'}`,
                (0, output_1.renderTerminalBoundary)({ kind: 'read-only' }),
            ].join('\n'),
        });
    });
}
async function createWorkClearCommand() {
    const { Command } = await import('commander');
    return new Command('clear')
        .description('Clear one named user-local work selection session.')
        .option('--session <name>', 'Named local session. Defaults to default.')
        .option('--if-match <token>', 'Opaque token from work current; required when the session exists.')
        .action((options, commandInstance) => {
        const format = requireFormat(commandInstance);
        const repositoryContext = resolveRepositoryContext(commandInstance);
        const result = (0, work_selection_1.clearWorkSelection)({ repositoryRoot: repositoryContext.root, ...options });
        (0, output_1.emitSuccess)({
            command: 'work clear',
            format,
            data: {
                ...result,
                writeApplied: result.changed,
                noOp: !result.changed,
                stateSurface: 'user-local work selection',
            },
            text: [
                result.changed ? 'Work selection cleared' : 'Work selection already absent',
                `Session: ${result.session}`,
                `Revision: ${result.storeRevision}`,
                (0, output_1.renderTerminalBoundary)(result.changed
                    ? { kind: 'write-applied', target: result.session, stateSurface: 'user-local work selection' }
                    : {
                        kind: 'mutating-no-op',
                        reason: 'The selected session had no stored work selection.',
                        target: result.session,
                        stateSurface: 'user-local work selection',
                    }),
            ].join('\n'),
        });
    });
}
async function createWorkCleanupCommand() {
    const { Command } = await import('commander');
    return new Command('cleanup')
        .description('Clear one stale named work selection while preserving fresh or absent state.')
        .option('--session <name>', 'Named local session. Defaults to default.')
        .option('--if-match <token>', 'Opaque token from work current; required to clear stale state.')
        .action((options, commandInstance) => {
        const format = requireFormat(commandInstance);
        const repositoryContext = resolveRepositoryContext(commandInstance);
        const result = (0, work_selection_1.cleanupStaleWorkSelection)({ repositoryRoot: repositoryContext.root, ...options });
        (0, output_1.emitSuccess)({
            command: 'work cleanup',
            format,
            data: {
                ...result,
                writeApplied: result.changed,
                noOp: !result.changed,
                stateSurface: 'user-local work selection',
            },
            text: [
                result.changed ? 'Stale work selection cleared' : 'Work selection cleanup made no change',
                `Session: ${result.session}`,
                `Reason: ${result.reason}`,
                `Revision: ${result.storeRevision}`,
                (0, output_1.renderTerminalBoundary)(result.changed
                    ? { kind: 'write-applied', target: result.session, stateSurface: 'user-local work selection' }
                    : {
                        kind: 'mutating-no-op',
                        reason: result.reason,
                        target: result.session,
                        stateSurface: 'user-local work selection',
                    }),
            ].join('\n'),
        });
    });
}
function assertResolvedSelection(resolution) {
    if (resolution.status === 'resolved')
        return;
    if (resolution.status === 'conflict') {
        throw new errors_1.RuntimeError({
            code: 'WORK_SELECTION_CONFLICT',
            exitCode: errors_1.RuntimeExitCode.CONCURRENCY_CONFLICT,
            message: 'Explicit artifact input conflicts with the active stored work selection.',
            details: [
                `Explicit artifact: ${resolution.conflict?.explicitArtifactPath}`,
                `Stored artifact: ${resolution.conflict?.storedArtifactPath}`,
                'No selection state was changed. Clear or replace the stored session explicitly, then retry.',
            ],
            recoveryActions: [
                (0, errors_1.createDescriptorBackedRecoveryAction)({
                    command: 'work clear',
                    argv: ['day-shift', 'work', 'clear', '--session', resolution.session],
                    explanation: 'Clear the conflicting stored selection explicitly, then rerun with the intended artifact.',
                }),
            ],
        });
    }
    if (resolution.status === 'stale') {
        throw new errors_1.RuntimeError({
            code: 'WORK_SELECTION_STALE',
            exitCode: errors_1.RuntimeExitCode.STALE_EVIDENCE,
            message: 'Stored work selection evidence is stale.',
            details: [
                `Reason: ${resolution.staleReason}`,
                'No selection state was changed. Run work select again with current artifact evidence.',
            ],
            recoveryActions: [
                (0, errors_1.createDescriptorBackedRecoveryAction)({
                    command: 'work current',
                    argv: ['day-shift', 'work', 'current', '--session', resolution.session, '--format', 'json'],
                    explanation: 'Refresh the current selection freshness and precondition evidence without writing state.',
                }),
                (0, errors_1.createDescriptorBackedRecoveryAction)({
                    command: 'work cleanup',
                    argv: [
                        'day-shift',
                        'work',
                        'cleanup',
                        '--session',
                        resolution.session,
                        '--if-match',
                        resolution.preconditionToken,
                        '--format',
                        'json',
                    ],
                    explanation: 'Clear the stale stored selection using the current precondition token.',
                }),
            ],
        });
    }
    throw new errors_1.RuntimeError({
        code: 'WORK_SELECTION_MISSING',
        exitCode: errors_1.RuntimeExitCode.USAGE,
        message: 'No work selection is available for next-action resolution.',
        details: ['Pass --artifact for this invocation or run work select explicitly. No selection state was changed.'],
        recoveryActions: [
            (0, errors_1.createDescriptorBackedRecoveryAction)({
                command: 'work candidates',
                argv: ['day-shift', 'work', 'candidates', '--max-results', '5', '--format', 'json', '--detail', 'compact'],
                explanation: 'List a bounded set of planning candidates before selecting an artifact explicitly.',
            }),
        ],
    });
}
function requireFormat(commandInstance) {
    const format = (0, output_1.resolveOutputFormat)(commandInstance.optsWithGlobals?.().format);
    if (format === null)
        throw (0, errors_1.createUsageError)('Output format must be one of: text, json.');
    return format;
}
function resolveRepositoryContext(commandInstance) {
    const rootCommand = (commandInstance?.parent?.parent ?? commandInstance);
    if (rootCommand?.configRepositoryContext)
        return rootCommand.configRepositoryContext;
    return (0, runtime_contract_1.createRepositoryContext)((0, runtime_contract_1.detectRepositoryRoot)(), false);
}
