"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.SANDBOX_ARTIFACT_PLACEMENT_CONTRACT = exports.LIFECYCLE_RUN_DIRECTORY_PATH_PATTERN = exports.LEGACY_SANDBOX_RUN_DIRECTORY_PATH_PATTERN = exports.SANDBOX_RUN_DIRECTORY_PATH_PATTERN = exports.SANDBOX_RUN_DIRECTORY_NAME_PATTERN = exports.SANDBOX_RUN_ID_PATTERN = exports.SANDBOX_RUN_DIRECTORY_PREFIX = exports.LEGACY_SANDBOX_PARENT_DIRECTORY = exports.SANDBOX_PARENT_DIRECTORY = void 0;
exports.isSandboxRunDirectoryName = isSandboxRunDirectoryName;
exports.composeSandboxRunDirectoryName = composeSandboxRunDirectoryName;
exports.composeSandboxRunDirectoryPath = composeSandboxRunDirectoryPath;
exports.classifySandboxArtifactPlacement = classifySandboxArtifactPlacement;
exports.isSandboxRunDirectoryPath = isSandboxRunDirectoryPath;
exports.isSandboxRunContentPath = isSandboxRunContentPath;
exports.assertSandboxRunDirectoryPath = assertSandboxRunDirectoryPath;
exports.assertSandboxRunContentPath = assertSandboxRunContentPath;
exports.isLegacySandboxRunDirectoryPath = isLegacySandboxRunDirectoryPath;
exports.assertLifecycleRunDirectoryPath = assertLifecycleRunDirectoryPath;
exports.assertLifecycleRunContentPath = assertLifecycleRunContentPath;
const node_path_1 = __importDefault(require("node:path"));
const path_contract_1 = require("./path-contract");
exports.SANDBOX_PARENT_DIRECTORY = ".day-shift/runs";
exports.LEGACY_SANDBOX_PARENT_DIRECTORY = "sandbox";
exports.SANDBOX_RUN_DIRECTORY_PREFIX = "run-";
exports.SANDBOX_RUN_ID_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;
exports.SANDBOX_RUN_DIRECTORY_NAME_PATTERN = /^run-[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;
exports.SANDBOX_RUN_DIRECTORY_PATH_PATTERN = /^\.day-shift\/runs\/run-[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;
exports.LEGACY_SANDBOX_RUN_DIRECTORY_PATH_PATTERN = /^sandbox\/run-[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;
exports.LIFECYCLE_RUN_DIRECTORY_PATH_PATTERN = /^(?:\.day-shift\/runs|sandbox)\/run-[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;
exports.SANDBOX_ARTIFACT_PLACEMENT_CONTRACT = Object.freeze({
    sandboxParentPath: exports.SANDBOX_PARENT_DIRECTORY,
    legacySandboxParentPath: exports.LEGACY_SANDBOX_PARENT_DIRECTORY,
    permittedRootEntry: "run-directory",
    permittedRunContent: "owned-descendant",
    rootLevelArtifacts: "forbidden"
});
function isSandboxRunDirectoryName(value) {
    return exports.SANDBOX_RUN_DIRECTORY_NAME_PATTERN.test(value);
}
function composeSandboxRunDirectoryName(runId) {
    if (runId === "") {
        throw new RangeError("Sandbox run IDs must not be empty.");
    }
    if (!exports.SANDBOX_RUN_ID_PATTERN.test(runId)) {
        throw new RangeError(`Sandbox run IDs must be filesystem-safe: ${runId}`);
    }
    return `${exports.SANDBOX_RUN_DIRECTORY_PREFIX}${runId}`;
}
function composeSandboxRunDirectoryPath(runId) {
    return node_path_1.default.posix.join(exports.SANDBOX_PARENT_DIRECTORY, composeSandboxRunDirectoryName(runId));
}
function classifySandboxArtifactPlacement(value) {
    const parsed = (0, path_contract_1.parseRepositoryRelativePath)(value);
    const parentSegments = exports.SANDBOX_PARENT_DIRECTORY.split("/");
    const belongsToManagedParent = parentSegments.every((segment, index) => parsed.segments[index] === segment);
    if (!belongsToManagedParent) {
        return {
            kind: "outside-sandbox",
            normalizedPath: parsed.normalizedPath,
            runDirectoryPath: null
        };
    }
    if (parsed.segments.length === parentSegments.length) {
        return {
            kind: "sandbox-parent",
            normalizedPath: parsed.normalizedPath,
            runDirectoryPath: null
        };
    }
    const runDirectoryName = parsed.segments[parentSegments.length];
    if (runDirectoryName === undefined || !isSandboxRunDirectoryName(runDirectoryName)) {
        return {
            kind: "misplaced-root-entry",
            normalizedPath: parsed.normalizedPath,
            runDirectoryPath: null
        };
    }
    const runDirectoryPath = node_path_1.default.posix.join(exports.SANDBOX_PARENT_DIRECTORY, runDirectoryName);
    return {
        kind: parsed.segments.length === parentSegments.length + 1 ? "run-directory" : "run-content",
        normalizedPath: parsed.normalizedPath,
        runDirectoryPath
    };
}
function isSandboxRunDirectoryPath(value) {
    try {
        return classifySandboxArtifactPlacement(value).kind === "run-directory";
    }
    catch {
        return false;
    }
}
function isSandboxRunContentPath(value) {
    try {
        return classifySandboxArtifactPlacement(value).kind === "run-content";
    }
    catch {
        return false;
    }
}
function assertSandboxRunDirectoryPath(value) {
    const placement = classifySandboxArtifactPlacement(value);
    if (placement.kind !== "run-directory") {
        throw new RangeError(`Sandbox run directory paths must match '${exports.SANDBOX_PARENT_DIRECTORY}/${exports.SANDBOX_RUN_DIRECTORY_PREFIX}<run-id>': ${value}`);
    }
    return placement.normalizedPath;
}
function assertSandboxRunContentPath(value) {
    const placement = classifySandboxArtifactPlacement(value);
    if (placement.kind !== "run-content") {
        throw new RangeError(`Sandbox artifacts must be placed beneath an owned '${exports.SANDBOX_PARENT_DIRECTORY}/${exports.SANDBOX_RUN_DIRECTORY_PREFIX}<run-id>/' directory: ${value}`);
    }
    return placement.normalizedPath;
}
function isLegacySandboxRunDirectoryPath(value) {
    try {
        return exports.LEGACY_SANDBOX_RUN_DIRECTORY_PATH_PATTERN.test((0, path_contract_1.parseRepositoryRelativePath)(value).normalizedPath);
    }
    catch {
        return false;
    }
}
function assertLifecycleRunDirectoryPath(value) {
    const normalizedPath = (0, path_contract_1.parseRepositoryRelativePath)(value).normalizedPath;
    if (!exports.LIFECYCLE_RUN_DIRECTORY_PATH_PATTERN.test(normalizedPath)) {
        throw new RangeError(`Lifecycle run directory paths must match '${exports.SANDBOX_PARENT_DIRECTORY}/${exports.SANDBOX_RUN_DIRECTORY_PREFIX}<run-id>'` +
            ` (legacy '${exports.LEGACY_SANDBOX_PARENT_DIRECTORY}/${exports.SANDBOX_RUN_DIRECTORY_PREFIX}<run-id>' remains readable): ${value}`);
    }
    return normalizedPath;
}
function assertLifecycleRunContentPath(value) {
    const normalizedPath = (0, path_contract_1.parseRepositoryRelativePath)(value).normalizedPath;
    const segments = normalizedPath.split("/");
    const runDirectoryPath = segments.slice(0, normalizedPath.startsWith(".day-shift/") ? 3 : 2).join("/");
    if (segments.length <= (normalizedPath.startsWith(".day-shift/") ? 3 : 2)
        || !exports.LIFECYCLE_RUN_DIRECTORY_PATH_PATTERN.test(runDirectoryPath)) {
        throw new RangeError(`Lifecycle evidence must be beneath '${exports.SANDBOX_PARENT_DIRECTORY}/${exports.SANDBOX_RUN_DIRECTORY_PREFIX}<run-id>/': ${value}`);
    }
    return normalizedPath;
}
