"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.createInitCommand = createInitCommand;
const node_path_1 = __importDefault(require("node:path"));
const runtime_contract_1 = require("../../../lib/runtime/runtime-contract");
const errors_1 = require("../../../lib/errors");
const command_write_summary_1 = require("../../../lib/license/command-write-summary");
const output_1 = require("../../../lib/output");
const workspace_init_1 = require("../../../lib/workspace-init");
const cli_constants_1 = require("../../../lib/config/cli-constants");
const sandbox_contract_1 = require("../../../lib/paths/sandbox-contract");
const INIT_IGNORE_HANDOFF_FINDING = Object.freeze({
    code: 'IGNORE_INSTALL_HANDOFF',
    message: cli_constants_1.CLI_INIT_IGNORE_HANDOFF_MESSAGE,
    severity: 'warning',
});
async function createInitCommand() {
    const { Command } = await import('commander');
    const command = new Command('init');
    command
        .description('Create the baseline Day Shift workspace scaffold.')
        .option('--no-agent', 'Skip scaffolding .day-shift/agents.md.')
        .option('--without-templates', 'Skip scaffolding shared authoring assets under .day-shift/prompts/user/, .day-shift/workflows/, and the local .day-shift/templates/ working surface.')
        .option('--dry-run', 'Show intended init changes without writing files.')
        .option('--force', 'Explicitly allow overwriting managed files with defaults.')
        .option('--directory <path>', 'Initialize under a specific directory (relative to current working directory or absolute).')
        .option('--sandbox-run-id [runId]', 'Create or reuse a disposable sandbox run directory; auto-generates a run ID when omitted.')
        .action((_, 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.', [
                `Received: ${String(commandInstance.optsWithGlobals().format)}`,
            ]);
        }
        const sandboxRunIdOption = commandInstance.opts().sandboxRunId;
        const createSandboxRunDirectory = sandboxRunIdOption !== undefined;
        const sandboxRunId = typeof sandboxRunIdOption === 'string' ? sandboxRunIdOption : undefined;
        if (sandboxRunId !== undefined) {
            try {
                (0, sandbox_contract_1.assertSandboxRunDirectoryPath)((0, sandbox_contract_1.composeSandboxRunDirectoryPath)(sandboxRunId));
            }
            catch (error) {
                throw (0, errors_1.createUsageError)("Sandbox run ID must produce one canonical '.day-shift/runs/run-<run-id>' directory.", [
                    error instanceof Error ? error.message : String(error),
                ]);
            }
        }
        const repositoryContext = (0, runtime_contract_1.createRepositoryContext)((0, runtime_contract_1.detectRepositoryRoot)(), false);
        const initTarget = resolveInitTargetDirectory({
            repositoryRoot: repositoryContext.root,
            cwd: process.cwd(),
            directoryOption: commandInstance.opts().directory,
        });
        const result = (0, workspace_init_1.executeInitSafetyPlan)({
            repositoryRoot: initTarget.absolutePath,
            dryRun: commandInstance.opts().dryRun,
            force: commandInstance.opts().force,
            scaffoldAgentEntrypoint: commandInstance.opts().agent,
            scaffoldSharedAuthoringAssets: !commandInstance.opts().withoutTemplates,
            createSandboxRunDirectory,
            sandboxRunId,
            operationPathPrefix: initTarget.pathPrefix,
        });
        const summary = summarizeOperations(result.operations);
        (0, output_1.emitSuccess)({
            command: 'init',
            format,
            text: createInitText(result.operations, result.dryRun),
            findings: [INIT_IGNORE_HANDOFF_FINDING],
            data: {
                repositoryRoot: repositoryContext.root,
                initTargetDirectory: initTarget.absolutePath,
                initTargetRelativePath: initTarget.relativePath,
                detectionSource: repositoryContext.detectionSource,
                dryRun: result.dryRun,
                operations: result.operations,
                sandbox: result.sandbox,
                summary,
                commandWriteSummary: createInitCommandWriteSummary(result.operations, result.dryRun, format === 'json'),
            },
        });
    });
    return command;
}
function createInitText(operations, dryRun) {
    const summary = summarizeOperations(operations);
    const writeOperationCount = operations.filter((operation) => operation.action === 'create' || operation.action === 'overwrite').length;
    const lines = [
        (0, output_1.renderTerminalHeading)('Workspace Initialization', 'title'),
        (0, output_1.renderTerminalSection)({
            heading: 'Summary',
            fields: [
                { label: 'Result', value: dryRun ? 'planned workspace scaffold changes' : 'workspace scaffold processed' },
                { label: 'Directories created', value: summary.directoriesCreated },
                { label: 'Directories kept', value: summary.directoriesKept },
                { label: 'Files created', value: summary.filesCreated },
                { label: 'Files overwritten', value: summary.filesOverwritten },
                { label: 'Files kept', value: summary.filesKept },
            ],
        }),
    ];
    const preservedExistingContent = operations.some((operation) => operation.type === 'file' &&
        operation.action === 'noop' &&
        operation.reason !== 'disabled' &&
        operation.reason !== 'matches-expected');
    lines.push('', (0, output_1.renderTerminalCompactList)({
        heading: 'Actions',
        entrySpacing: 'compact',
        entries: operations.map((operation) => ({
            label: renderInitOperationLabel(operation),
            fields: [
                { label: 'Path', value: operation.path },
                { label: 'Type', value: operation.type },
                { label: 'Outcome', value: operation.writeOutcome },
                ...(operation.type === 'file' && operation.reason === 'disabled'
                    ? [{ label: 'Disabled by', value: formatDisabledOptionHint(operation.disabledBy) }]
                    : []),
                ...(operation.type === 'file' && operation.reason !== 'disabled'
                    ? [{ label: 'Reason', value: formatInitOperationReason(operation.reason) }]
                    : []),
            ],
        })),
    }));
    lines.push('', (0, output_1.renderTerminalSection)({
        heading: 'Write Boundary',
        lines: [
            dryRun
                ? (0, output_1.renderTerminalBoundary)({ kind: 'dry-run' })
                : writeOperationCount > 0
                    ? (0, output_1.renderTerminalBoundary)({
                        kind: 'write-applied',
                        target: 'Day Shift workspace scaffold',
                    })
                    : (0, output_1.renderTerminalBoundary)({
                        kind: 'mutating-no-op',
                        reason: 'Workspace scaffold already matched the intended state.',
                        target: 'Day Shift workspace scaffold',
                    }),
        ],
    }));
    if (preservedExistingContent) {
        lines.push('', (0, output_1.renderTerminalSection)({
            heading: 'Recovery',
            lines: [
                'Review preserved files, compare them with packaged defaults, and rerun with --force only when replacement is intended.',
            ],
        }));
    }
    lines.push('', (0, output_1.renderTerminalSection)({
        heading: 'Next Action',
        lines: [(0, output_1.renderTerminalNextAction)({ command: 'day-shift ignore install' }), cli_constants_1.CLI_INIT_IGNORE_HANDOFF_MESSAGE],
    }));
    return lines.join('\n');
}
function createInitCommandWriteSummary(operations, dryRun, jsonOnly) {
    const fileOperations = operations.filter((operation) => operation.type === 'file');
    return (0, command_write_summary_1.normalizeCommandWriteSummary)({
        commandFamily: 'workspace_init',
        dryRun,
        jsonOnly,
        primaryOutputArtifacts: fileOperations.map((operation) => operation.path),
        updatedArtifacts: fileOperations.map((operation) => ({
            path: operation.path,
            action: initOperationAction(operation),
            reason: initOperationMaterialUpdate(operation, dryRun) ? undefined : initOperationReason(operation, dryRun),
            materialUpdate: initOperationMaterialUpdate(operation, dryRun),
        })),
    });
}
function initOperationAction(operation) {
    if (operation.action === 'create') {
        return 'created';
    }
    if (operation.action === 'overwrite') {
        return 'rewritten';
    }
    return 'kept';
}
function initOperationReason(operation, dryRun) {
    if (dryRun && (operation.action === 'create' || operation.action === 'overwrite')) {
        return 'dry_run';
    }
    if (operation.action === 'create') {
        return 'non_coordination_artifact';
    }
    if (operation.action === 'overwrite') {
        return 'non_coordination_artifact';
    }
    return 'no_write';
}
function initOperationMaterialUpdate(operation, dryRun) {
    const normalizedPath = operation.path.replace(/\\/g, '/');
    return (!dryRun &&
        /(?:^|\/)\.day-shift\/planning\//.test(normalizedPath) &&
        (operation.action === 'create' || operation.action === 'overwrite'));
}
function resolveInitTargetDirectory(options) {
    const repositoryRootAbsolute = node_path_1.default.resolve(options.repositoryRoot);
    if (options.directoryOption === undefined) {
        return {
            absolutePath: repositoryRootAbsolute,
            relativePath: '.',
        };
    }
    const candidateAbsolutePath = node_path_1.default.resolve(options.cwd, options.directoryOption);
    const relativePath = node_path_1.default.relative(repositoryRootAbsolute, candidateAbsolutePath);
    if (relativePath.startsWith('..') || node_path_1.default.isAbsolute(relativePath)) {
        throw (0, errors_1.createUsageError)('Init directory must be inside the detected repository root.', [
            `Repository root: ${repositoryRootAbsolute}`,
            `Requested directory: ${candidateAbsolutePath}`,
            'Choose a directory under the repository root and rerun.',
        ]);
    }
    const normalizedRelativePath = relativePath.split(node_path_1.default.sep).join('/');
    return {
        absolutePath: candidateAbsolutePath,
        relativePath: normalizedRelativePath.length === 0 ? '.' : normalizedRelativePath,
        pathPrefix: normalizedRelativePath.length === 0 ? undefined : normalizedRelativePath,
    };
}
function renderInitOperationLabel(operation) {
    if (operation.type === 'directory') {
        return `${operation.action === 'create' ? 'Create' : 'Keep'} ${operation.path}`;
    }
    if (operation.action === 'create') {
        return `Create ${operation.path}`;
    }
    if (operation.action === 'overwrite') {
        return `Overwrite ${operation.path} (--force)`;
    }
    if (operation.reason === 'disabled') {
        return `Skip ${operation.path} (${formatDisabledOptionHint(operation.disabledBy)})`;
    }
    if (operation.reason === 'matches-expected') {
        return `Keep ${operation.path} (already matches defaults)`;
    }
    return `Keep ${operation.path} (preserve existing content)`;
}
function formatInitOperationReason(reason) {
    if (reason === 'missing') {
        return 'target missing';
    }
    if (reason === 'matches-expected') {
        return 'already matches defaults';
    }
    if (reason === 'force-overwrite') {
        return 'force overwrite requested';
    }
    if (reason === 'preserved-existing') {
        return 'preserve existing content';
    }
    return reason;
}
function formatDisabledOptionHint(disabledBy) {
    if (disabledBy === 'no-agent') {
        return '--no-agent';
    }
    return '--without-templates';
}
function summarizeOperations(operations) {
    const summary = {
        directoriesCreated: 0,
        directoriesKept: 0,
        filesCreated: 0,
        filesOverwritten: 0,
        filesKept: 0,
    };
    for (const operation of operations) {
        if (operation.type === 'directory') {
            if (operation.action === 'create') {
                summary.directoriesCreated += 1;
            }
            else {
                summary.directoriesKept += 1;
            }
            continue;
        }
        if (operation.action === 'create') {
            summary.filesCreated += 1;
        }
        else if (operation.action === 'overwrite') {
            summary.filesOverwritten += 1;
        }
        else {
            summary.filesKept += 1;
        }
    }
    return summary;
}
