import { createHash } from "crypto";
const SECRET_PATTERNS = [
    /github_pat_[A-Za-z0-9_]+/gu,
    /gh[pousr]_[A-Za-z0-9_]+/gu,
    /sk-[A-Za-z0-9_-]{12,}/gu,
    /\b([A-Z0-9_]*(?:KEY|TOKEN|SECRET|PASSWORD|CREDENTIAL)[A-Z0-9_]*=)([^\s]+)/giu,
    /\b((?:--?)(?:api[-_]?key|token|secret|password|credential)(?:=|\s+))([^\s]+)/giu,
];
export function sanitizeInputTextForArtifact(value) {
    let text = value;
    let redactionCount = 0;
    for (const pattern of SECRET_PATTERNS) {
        text = text.replace(pattern, (...args) => {
            redactionCount += 1;
            if (typeof args[1] === "string" &&
                pattern.source.startsWith("\\b([A-Z0-9_]*")) {
                return `${args[1]}[REDACTED:secret]`;
            }
            if (typeof args[1] === "string" &&
                pattern.source.startsWith("\\b((?:--?)")) {
                return `${args[1]}[REDACTED:secret]`;
            }
            return "[REDACTED:secret]";
        });
    }
    return { text, redactionCount };
}
export function normalizeInputText(raw) {
    return raw.trim().replace(/\s+/gu, " ");
}
export function normalizeMcpScope(value) {
    const normalized = value?.trim().toLowerCase();
    if (normalized === "all" || normalized === "project" || normalized === "none")
        return normalized;
    return undefined;
}
export function buildInputEnvelope(input) {
    const createdAt = (input.now ?? (() => new Date()))().toISOString();
    const sanitizedRaw = sanitizeInputTextForArtifact(input.raw);
    const sanitizedNormalized = sanitizeInputTextForArtifact(normalizeInputText(input.raw));
    const inputId = createInputId(input.runId, input.kind, sanitizedNormalized.text, createdAt);
    return {
        schemaVersion: 1,
        inputId,
        runId: input.runId,
        sessionId: input.sessionId,
        kind: input.kind,
        raw: sanitizedRaw.text,
        normalized: sanitizedNormalized.text,
        redactionCount: sanitizedRaw.redactionCount + sanitizedNormalized.redactionCount,
        source: input.source,
        cwd: input.cwd,
        root: input.root,
        rootSource: input.rootSource,
        provider: input.provider,
        model: input.model,
        mcpScope: input.mcpScope,
        ui: input.ui,
        view: input.view,
        theme: input.theme,
        constraints: [...(input.constraints ?? [])],
        requestedArtifacts: input.requestedArtifacts?.map((artifact) => ({ ...artifact })) ?? [],
        slashCommand: input.slashCommand
            ? cloneSlashCommand(input.slashCommand)
            : undefined,
        createdAt,
    };
}
function createInputId(runId, kind, normalized, createdAt) {
    const digest = createHash("sha256")
        .update(`${runId}\0${kind}\0${normalized}\0${createdAt}`)
        .digest("hex")
        .slice(0, 12);
    return `input-${createdAt.replace(/[:.]/gu, "-")}-${digest}`;
}
function cloneSlashCommand(input) {
    const flags = {};
    for (const [key, value] of Object.entries(input.flags))
        flags[key] = Array.isArray(value) ? [...value] : value;
    return {
        command: input.command,
        argv: [...input.argv],
        positional: [...input.positional],
        flags,
    };
}
