"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.DEFAULT_COMPACT_COLLECTION_PAGE_SIZE = void 0;
exports.getCompactCollectionProfile = getCompactCollectionProfile;
exports.getStablePaginationRecordId = getStablePaginationRecordId;
exports.createPageContinuationCommand = createPageContinuationCommand;
exports.renderPageContinuation = renderPageContinuation;
const node_crypto_1 = require("node:crypto");
exports.DEFAULT_COMPACT_COLLECTION_PAGE_SIZE = 10;
const IDENTITY_FIELDS = ["id", "command", "name", "path"];
const COMPACT_COLLECTION_PROFILES = Object.freeze({
    "spec list": profile("spec list", "entries"),
    "spec search": profile("spec search", "entries"),
    "commands inventory": profile("commands inventory", "entries", compactCommandInventory),
    "commands manifest": profile("commands manifest", "tools", identityProjection, 1),
    "commands search": profile("commands search", "matches")
});
function getCompactCollectionProfile(command) {
    return COMPACT_COLLECTION_PROFILES[command];
}
function getStablePaginationRecordId(value) {
    if (isRecord(value)) {
        for (const field of IDENTITY_FIELDS) {
            const identity = value[field];
            if (isScalar(identity)) {
                return scalarIdentity(identity);
            }
        }
    }
    if (isScalar(value)) {
        return scalarIdentity(value);
    }
    return hashJsonValue(value);
}
function createPageContinuationCommand(argv, cursor) {
    const args = argv.slice(2);
    const continued = [];
    let replaced = false;
    for (let index = 0; index < args.length; index += 1) {
        const token = args[index];
        if (token === "--page-cursor") {
            continued.push(token, cursor);
            replaced = true;
            index += 1;
        }
        else if (token.startsWith("--page-cursor=")) {
            continued.push(`--page-cursor=${cursor}`);
            replaced = true;
        }
        else {
            continued.push(token);
        }
    }
    if (!replaced) {
        continued.push("--page-cursor", cursor);
    }
    return ["day-shift", ...continued].map(quoteShellArgument).join(" ");
}
function renderPageContinuation(command) {
    return `Next page: ${command}`;
}
function profile(command, lane, projectData = identityProjection, pageSize = exports.DEFAULT_COMPACT_COLLECTION_PAGE_SIZE) {
    return Object.freeze({ command, lane, pageSize, projectData });
}
function identityProjection(data) {
    return data;
}
function compactCommandInventory(data) {
    const entries = Array.isArray(data.entries)
        ? data.entries.map((entry) => isRecord(entry) ? pick(entry, [
            "command",
            "availability",
            "callable",
            "executableEligibility",
            "writeCapable",
            "capability",
            "artifactFamily",
            "mutationPosture",
            "authorization",
            "selectedArtifactRequired"
        ]) : entry)
        : data.entries;
    const coverage = isRecord(data.coverage)
        ? {
            ...pick(data.coverage, [
                "callableCount",
                "runtimeActionCount",
                "callableDescriptorCount",
                "registryCount",
                "mergedCount"
            ]),
            callableMissingCapabilityCount: arrayCount(data.coverage.callableMissingCapability),
            callableDescriptorMissingRuntimeActionCount: arrayCount(data.coverage.callableDescriptorMissingRuntimeAction),
            runtimeActionMissingCallableDescriptorCount: arrayCount(data.coverage.runtimeActionMissingCallableDescriptor),
            intentionalNonCallableCount: arrayCount(data.coverage.intentionalNonCallable),
            registryOnlyCount: arrayCount(data.coverage.registryOnly),
            mixedPostureFamilyCount: arrayCount(data.coverage.mixedPostureFamilies)
        }
        : data.coverage;
    return { ...data, entries, coverage };
}
function pick(source, fields) {
    return Object.fromEntries(fields
        .filter((field) => Object.hasOwn(source, field))
        .map((field) => [field, source[field]]));
}
function arrayCount(value) {
    return Array.isArray(value) ? value.length : 0;
}
function quoteShellArgument(value) {
    if (/^[A-Za-z0-9_./:@%+=,-]+$/u.test(value)) {
        return value;
    }
    return `'${value.replace(/'/g, `'"'"'`)}'`;
}
function hashJsonValue(value) {
    const serialized = JSON.stringify(value);
    if (serialized === undefined) {
        throw new TypeError("Pagination record identities require JSON-serializable values.");
    }
    return `sha256:${(0, node_crypto_1.createHash)("sha256").update(serialized).digest("hex")}`;
}
function scalarIdentity(value) {
    return value === null ? "null" : String(value);
}
function isScalar(value) {
    return value === null || ["string", "number", "boolean"].includes(typeof value);
}
function isRecord(value) {
    return typeof value === "object" && value !== null && !Array.isArray(value);
}
