"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.installManagedVersion = installManagedVersion;
const node_fs_1 = __importDefault(require("node:fs"));
const node_path_1 = __importDefault(require("node:path"));
const state_layout_1 = require("./state-layout");
const install_source_1 = require("./install-source");
function installManagedVersion(options) {
    const versionManagerRoot = (0, state_layout_1.resolveVersionManagerRoot)(options);
    const stagingDirectory = options.stagingDirectory ?? node_path_1.default.join(versionManagerRoot, "cache", "install-staging");
    const validation = (0, install_source_1.validateVersionInstallSource)({
        sourcePath: options.sourcePath,
        stagingDirectory,
        assertedVersion: options.assertedVersion,
        env: options.env
    });
    if (validation.status === "invalid") {
        throw new Error([
            validation.message,
            `Reason: ${validation.reason}`,
            ...validation.details
        ].join("\n"));
    }
    const layout = (0, state_layout_1.initializeVersionManagerLayout)(options);
    const installedAt = options.installedAt ?? new Date().toISOString();
    const managedVersionDirectory = node_path_1.default.join(layout.versionManagerRoot, "versions", validation.version);
    const managedPackageDirectory = node_path_1.default.join(managedVersionDirectory, "package");
    const metadataPath = node_path_1.default.join(managedVersionDirectory, "metadata.json");
    const receiptPath = node_path_1.default.join(layout.versionManagerRoot, "installs", "receipts", `${validation.version}-${installedAt.replace(/[:.]/g, "-")}.json`);
    const replacedExistingPackage = node_fs_1.default.existsSync(managedPackageDirectory);
    node_fs_1.default.rmSync(managedPackageDirectory, { recursive: true, force: true });
    node_fs_1.default.mkdirSync(managedVersionDirectory, { recursive: true });
    node_fs_1.default.cpSync(validation.packageRoot, managedPackageDirectory, {
        recursive: true,
        dereference: false,
        force: true
    });
    const copiedCommandPath = remapCommandPath(validation, managedPackageDirectory);
    const metadata = {
        schemaVersion: 1,
        version: validation.version,
        packageName: validation.packageName,
        commandName: validation.commandName,
        commandPath: copiedCommandPath,
        sourceKind: validation.sourceKind,
        sourcePath: validation.sourcePath,
        checksumStatus: validation.checksumStatus,
        runtimeRequirement: validation.runtimeRequirement,
        installedAt
    };
    const receipt = {
        schemaVersion: 1,
        action: replacedExistingPackage ? "replace" : "install",
        version: validation.version,
        sourcePath: validation.sourcePath,
        sourceKind: validation.sourceKind,
        packageRoot: validation.packageRoot,
        managedPackageDirectory,
        commandPath: copiedCommandPath,
        checksumStatus: validation.checksumStatus,
        runtimeRequirement: validation.runtimeRequirement,
        installedAt,
        networkAttempted: false
    };
    node_fs_1.default.writeFileSync(metadataPath, `${JSON.stringify(metadata, null, 2)}\n`);
    node_fs_1.default.writeFileSync(receiptPath, `${JSON.stringify(receipt, null, 2)}\n`);
    return {
        versionManagerRoot: layout.versionManagerRoot,
        version: validation.version,
        sourcePath: validation.sourcePath,
        sourceKind: validation.sourceKind,
        packageRoot: validation.packageRoot,
        managedVersionDirectory,
        managedPackageDirectory,
        metadataPath,
        receiptPath,
        commandPath: copiedCommandPath,
        checksumStatus: validation.checksumStatus,
        runtimeRequirement: validation.runtimeRequirement,
        installedAt,
        replacedExistingPackage,
        networkAttempted: false
    };
}
function remapCommandPath(validation, managedPackageDirectory) {
    const relativeCommandPath = node_path_1.default.relative(validation.packageRoot, validation.commandPath);
    return node_path_1.default.join(managedPackageDirectory, relativeCommandPath);
}
