"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.normalizeCanonicalSlug = exports.isOrderedPrefixCompatibleSlugName = exports.isCanonicalSlug = exports.composeOrderedSlugName = exports.SLUG_REJECTION_CODES = exports.toRepositoryRelativePath = exports.SANDBOX_RUN_DIRECTORY_PREFIX = exports.SANDBOX_PARENT_DIRECTORY = exports.composeSandboxRunDirectoryPath = exports.composeSandboxRunDirectoryName = exports.resolveRuntimeAbsolutePath = exports.resolveRepositoryRelativePath = exports.parseRepositoryRelativePath = exports.pathsOverlap = exports.pathsEqualForFilesystem = exports.isAbsolutePathLike = exports.createCanonicalPathPolicy = exports.TARGET_PATH_PLATFORMS = exports.PATH_VALUE_KINDS = exports.resolvePlanningOverviewPath = exports.resolvePlanningOverviewInputPath = exports.getPlanningOverviewCandidates = exports.getCanonicalPlanningOverviewFilename = exports.composeLegacyPlanningOverviewPath = exports.composeCanonicalPlanningOverviewPath = exports.PLANNING_OVERVIEW_LAYERS = exports.LEGACY_PLANNING_OVERVIEW_FILENAME = exports.validateWriteDestination = exports.assertWriteDestination = exports.assertCanonicalWriteTarget = exports.DestinationSafetyError = exports.DESTINATION_REJECTION_CODES = exports.resolveCanonicalWriteTargetSync = exports.CanonicalWriteTargetError = exports.CANONICAL_WRITE_TARGET_ERROR_CODES = void 0;
exports.resolveAtomicOutputFileTargetSync = resolveAtomicOutputFileTargetSync;
exports.writeAtomicOutputFileSync = writeAtomicOutputFileSync;
const node_crypto_1 = require("node:crypto");
const node_fs_1 = __importDefault(require("node:fs"));
const node_path_1 = __importDefault(require("node:path"));
const canonical_write_target_1 = require("./canonical-write-target");
const destination_contract_1 = require("./destination-contract");
function resolveAtomicOutputFileTargetSync(repositoryRoot, inputPath) {
    const safeDestination = (0, destination_contract_1.assertWriteDestination)(inputPath);
    const root = node_fs_1.default.realpathSync(node_path_1.default.resolve(repositoryRoot));
    const segments = safeDestination.repositoryRelativePath.segments;
    for (let index = 0; index < segments.length; index += 1) {
        const candidate = node_path_1.default.join(root, ...segments.slice(0, index + 1));
        const stats = node_fs_1.default.lstatSync(candidate, { throwIfNoEntry: false });
        if (stats === undefined) {
            if (index < segments.length - 1) {
                throw new TypeError(`Output-file parent '${segments.slice(0, index + 1).join("/")}' must already exist.`);
            }
            break;
        }
        if (stats.isSymbolicLink()) {
            throw new TypeError(`Output-file path '${inputPath}' must not contain or target a symbolic link.`);
        }
        if (index < segments.length - 1 && !stats.isDirectory()) {
            throw new TypeError(`Output-file parent '${segments.slice(0, index + 1).join("/")}' must be a directory.`);
        }
        if (index === segments.length - 1) {
            throw new TypeError(`Output file '${inputPath}' already exists and will not be overwritten.`);
        }
    }
    const target = (0, canonical_write_target_1.resolveCanonicalWriteTargetSync)(root, safeDestination.repositoryRelativePath.normalizedPath);
    if (target.exists) {
        throw new TypeError(`Output file '${inputPath}' already exists and will not be overwritten.`);
    }
    return {
        repositoryRelativePath: target.repositoryRelativePath,
        runtimePath: target.runtimePath
    };
}
function writeAtomicOutputFileSync(target, contents) {
    if (contents.length === 0) {
        throw new TypeError("Atomic output-file persistence requires non-empty contents.");
    }
    const temporaryPath = node_path_1.default.join(node_path_1.default.dirname(target.runtimePath), `.${node_path_1.default.basename(target.runtimePath)}.tmp-${process.pid}-${(0, node_crypto_1.randomBytes)(8).toString("hex")}`);
    let descriptor = null;
    try {
        descriptor = node_fs_1.default.openSync(temporaryPath, node_fs_1.default.constants.O_CREAT
            | node_fs_1.default.constants.O_EXCL
            | node_fs_1.default.constants.O_WRONLY
            | (node_fs_1.default.constants.O_NOFOLLOW ?? 0), 0o600);
        const bytes = Buffer.from(contents, "utf8");
        let offset = 0;
        while (offset < bytes.length) {
            const written = node_fs_1.default.writeSync(descriptor, bytes, offset, bytes.length - offset);
            if (written <= 0) {
                throw new Error(`Atomic output-file write made no progress after ${offset} of ${bytes.length} bytes.`);
            }
            offset += written;
        }
        node_fs_1.default.fsyncSync(descriptor);
        node_fs_1.default.closeSync(descriptor);
        descriptor = null;
        // Hard-linking the fully synced temporary inode creates the destination
        // atomically and fails rather than replacing any concurrently created path.
        node_fs_1.default.linkSync(temporaryPath, target.runtimePath);
    }
    finally {
        if (descriptor !== null) {
            node_fs_1.default.closeSync(descriptor);
        }
        node_fs_1.default.rmSync(temporaryPath, { force: true });
    }
}
var canonical_write_target_2 = require("./canonical-write-target");
Object.defineProperty(exports, "CANONICAL_WRITE_TARGET_ERROR_CODES", { enumerable: true, get: function () { return canonical_write_target_2.CANONICAL_WRITE_TARGET_ERROR_CODES; } });
Object.defineProperty(exports, "CanonicalWriteTargetError", { enumerable: true, get: function () { return canonical_write_target_2.CanonicalWriteTargetError; } });
Object.defineProperty(exports, "resolveCanonicalWriteTargetSync", { enumerable: true, get: function () { return canonical_write_target_2.resolveCanonicalWriteTargetSync; } });
var destination_contract_2 = require("./destination-contract");
Object.defineProperty(exports, "DESTINATION_REJECTION_CODES", { enumerable: true, get: function () { return destination_contract_2.DESTINATION_REJECTION_CODES; } });
Object.defineProperty(exports, "DestinationSafetyError", { enumerable: true, get: function () { return destination_contract_2.DestinationSafetyError; } });
Object.defineProperty(exports, "assertCanonicalWriteTarget", { enumerable: true, get: function () { return destination_contract_2.assertCanonicalWriteTarget; } });
Object.defineProperty(exports, "assertWriteDestination", { enumerable: true, get: function () { return destination_contract_2.assertWriteDestination; } });
Object.defineProperty(exports, "validateWriteDestination", { enumerable: true, get: function () { return destination_contract_2.validateWriteDestination; } });
var planning_overview_policy_1 = require("./planning-overview-policy");
Object.defineProperty(exports, "LEGACY_PLANNING_OVERVIEW_FILENAME", { enumerable: true, get: function () { return planning_overview_policy_1.LEGACY_PLANNING_OVERVIEW_FILENAME; } });
Object.defineProperty(exports, "PLANNING_OVERVIEW_LAYERS", { enumerable: true, get: function () { return planning_overview_policy_1.PLANNING_OVERVIEW_LAYERS; } });
Object.defineProperty(exports, "composeCanonicalPlanningOverviewPath", { enumerable: true, get: function () { return planning_overview_policy_1.composeCanonicalPlanningOverviewPath; } });
Object.defineProperty(exports, "composeLegacyPlanningOverviewPath", { enumerable: true, get: function () { return planning_overview_policy_1.composeLegacyPlanningOverviewPath; } });
Object.defineProperty(exports, "getCanonicalPlanningOverviewFilename", { enumerable: true, get: function () { return planning_overview_policy_1.getCanonicalPlanningOverviewFilename; } });
Object.defineProperty(exports, "getPlanningOverviewCandidates", { enumerable: true, get: function () { return planning_overview_policy_1.getPlanningOverviewCandidates; } });
Object.defineProperty(exports, "resolvePlanningOverviewInputPath", { enumerable: true, get: function () { return planning_overview_policy_1.resolvePlanningOverviewInputPath; } });
Object.defineProperty(exports, "resolvePlanningOverviewPath", { enumerable: true, get: function () { return planning_overview_policy_1.resolvePlanningOverviewPath; } });
var path_contract_1 = require("./path-contract");
Object.defineProperty(exports, "PATH_VALUE_KINDS", { enumerable: true, get: function () { return path_contract_1.PATH_VALUE_KINDS; } });
Object.defineProperty(exports, "TARGET_PATH_PLATFORMS", { enumerable: true, get: function () { return path_contract_1.TARGET_PATH_PLATFORMS; } });
Object.defineProperty(exports, "createCanonicalPathPolicy", { enumerable: true, get: function () { return path_contract_1.createCanonicalPathPolicy; } });
Object.defineProperty(exports, "isAbsolutePathLike", { enumerable: true, get: function () { return path_contract_1.isAbsolutePathLike; } });
Object.defineProperty(exports, "pathsEqualForFilesystem", { enumerable: true, get: function () { return path_contract_1.pathsEqualForFilesystem; } });
Object.defineProperty(exports, "pathsOverlap", { enumerable: true, get: function () { return path_contract_1.pathsOverlap; } });
Object.defineProperty(exports, "parseRepositoryRelativePath", { enumerable: true, get: function () { return path_contract_1.parseRepositoryRelativePath; } });
Object.defineProperty(exports, "resolveRepositoryRelativePath", { enumerable: true, get: function () { return path_contract_1.resolveRepositoryRelativePath; } });
Object.defineProperty(exports, "resolveRuntimeAbsolutePath", { enumerable: true, get: function () { return path_contract_1.resolveRuntimeAbsolutePath; } });
var sandbox_contract_1 = require("./sandbox-contract");
Object.defineProperty(exports, "composeSandboxRunDirectoryName", { enumerable: true, get: function () { return sandbox_contract_1.composeSandboxRunDirectoryName; } });
Object.defineProperty(exports, "composeSandboxRunDirectoryPath", { enumerable: true, get: function () { return sandbox_contract_1.composeSandboxRunDirectoryPath; } });
Object.defineProperty(exports, "SANDBOX_PARENT_DIRECTORY", { enumerable: true, get: function () { return sandbox_contract_1.SANDBOX_PARENT_DIRECTORY; } });
Object.defineProperty(exports, "SANDBOX_RUN_DIRECTORY_PREFIX", { enumerable: true, get: function () { return sandbox_contract_1.SANDBOX_RUN_DIRECTORY_PREFIX; } });
var repository_relative_1 = require("./repository-relative");
Object.defineProperty(exports, "toRepositoryRelativePath", { enumerable: true, get: function () { return repository_relative_1.toRepositoryRelativePath; } });
var slug_contract_1 = require("./slug-contract");
Object.defineProperty(exports, "SLUG_REJECTION_CODES", { enumerable: true, get: function () { return slug_contract_1.SLUG_REJECTION_CODES; } });
Object.defineProperty(exports, "composeOrderedSlugName", { enumerable: true, get: function () { return slug_contract_1.composeOrderedSlugName; } });
Object.defineProperty(exports, "isCanonicalSlug", { enumerable: true, get: function () { return slug_contract_1.isCanonicalSlug; } });
Object.defineProperty(exports, "isOrderedPrefixCompatibleSlugName", { enumerable: true, get: function () { return slug_contract_1.isOrderedPrefixCompatibleSlugName; } });
Object.defineProperty(exports, "normalizeCanonicalSlug", { enumerable: true, get: function () { return slug_contract_1.normalizeCanonicalSlug; } });
