"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.SENSITIVE_OMITTED = void 0;
exports.sanitizeOutputText = sanitizeOutputText;
exports.sanitizeOutputValue = sanitizeOutputValue;
const node_path_1 = __importDefault(require("node:path"));
exports.SENSITIVE_OMITTED = '<sensitive-omitted>';
const SENSITIVE_KEY = /(?:^|[_-])(credential|password|secret|token|api[_-]?key|private[_-]?key|license[_-]?(?:key|material|contents?))(?:$|[_-])/i;
const CREDENTIAL_VALUE = /\b(?:bearer\s+[a-z0-9._~+/-]{8,}|(?:gh[pousr]|sk|xox[baprs])[-_][a-z0-9_-]{8,})\b/gi;
function sanitizeOutputText(value, options = {}) {
    let safe = stripAnsiAndOsc(value);
    safe = removeUnsafeControls(safe);
    safe = safe.replace(CREDENTIAL_VALUE, exports.SENSITIVE_OMITTED);
    const repositoryRoot = normalizeAbsolute(options.repositoryRoot);
    if (repositoryRoot !== null) {
        safe = replacePathPrefix(safe, repositoryRoot, '.');
    }
    const home = normalizeAbsolute(options.homeDirectory ?? options.environment?.HOME ?? options.environment?.USERPROFILE);
    if (home !== null && home !== repositoryRoot) {
        safe = replacePathPrefix(safe, home, exports.SENSITIVE_OMITTED);
    }
    for (const [key, raw] of Object.entries(options.environment ?? {})) {
        if (typeof raw !== 'string' || raw.length < 8 || !SENSITIVE_KEY.test(key))
            continue;
        safe = safe.split(raw).join(exports.SENSITIVE_OMITTED);
    }
    return safe;
}
function stripAnsiAndOsc(value) {
    let result = '';
    for (let index = 0; index < value.length; index += 1) {
        const codePoint = value.charCodeAt(index);
        if (codePoint !== 27) {
            result += value[index];
            continue;
        }
        const next = value[index + 1];
        if (next === '[') {
            index += 2;
            while (index < value.length) {
                const candidate = value.charCodeAt(index);
                if (candidate >= 64 && candidate <= 126) {
                    break;
                }
                index += 1;
            }
            continue;
        }
        if (next === ']') {
            index += 2;
            while (index < value.length) {
                const candidate = value.charCodeAt(index);
                if (candidate === 7) {
                    break;
                }
                if (candidate === 27 && value[index + 1] === '\\') {
                    index += 1;
                    break;
                }
                index += 1;
            }
            continue;
        }
    }
    return result;
}
function removeUnsafeControls(value) {
    let result = '';
    for (let index = 0; index < value.length; index += 1) {
        const codePoint = value.charCodeAt(index);
        const isUnsafe = (codePoint >= 0 && codePoint <= 8) ||
            codePoint === 11 ||
            codePoint === 12 ||
            (codePoint >= 14 && codePoint <= 26) ||
            (codePoint >= 28 && codePoint <= 31) ||
            (codePoint >= 127 && codePoint <= 159);
        if (!isUnsafe) {
            result += value[index];
        }
    }
    return result;
}
function sanitizeOutputValue(value, options = {}) {
    return visit(value, options, new WeakMap());
}
function visit(value, options, seen) {
    if (typeof value === 'string')
        return sanitizeOutputText(value, options);
    if (value === null || typeof value !== 'object')
        return value;
    const existing = seen.get(value);
    if (existing !== undefined)
        return existing;
    if (Array.isArray(value)) {
        const result = [];
        seen.set(value, result);
        for (const item of value)
            result.push(visit(item, options, seen));
        return result;
    }
    const result = {};
    seen.set(value, result);
    for (const [key, item] of Object.entries(value)) {
        result[key] =
            SENSITIVE_KEY.test(key) && item !== null && item !== undefined ? exports.SENSITIVE_OMITTED : visit(item, options, seen);
    }
    return result;
}
function normalizeAbsolute(value) {
    if (value === undefined || !node_path_1.default.isAbsolute(value))
        return null;
    return node_path_1.default.resolve(value).replace(/[\\/]+$/, '');
}
function replacePathPrefix(value, prefix, replacement) {
    const escaped = prefix.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
    return value.replace(new RegExp(`${escaped}(?=[\\/]|$)`, 'g'), replacement);
}
