"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 IGNORE_HANDOFF_MESSAGE = "Run 'day-shift ignore install' to install recommended local-only ignore rules (.day-shift/planning/ and .day-shift/local.toml).";
const INIT_IGNORE_HANDOFF_FINDING = Object.freeze({
    code: "IGNORE_INSTALL_HANDOFF",
    message: 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;
        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" }), 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;
}
