/**
 * src/telemetry/scrubber.ts
 *
 * PII scrubber that runs at the SOURCE — before any data leaves the
 * customer's device for TaseesAI's training pipeline.
 *
 * Rule: if you can't reconstruct the original value from the scrubbed
 * version, you've done your job. This is THE compliance load-bearing
 * function for PDPL Article 11. Every regex here is a promise to the
 * customer.
 */
const PATTERNS = [
    // Saudi phone numbers
    { name: 'phone-saudi-intl', re: /\+966\d{8,9}/g, placeholder: '<PHONE_SA>' },
    { name: 'phone-saudi-local', re: /\b05\d{8}\b/g, placeholder: '<PHONE_SA>' },
    { name: 'phone-intl', re: /\+\d{10,15}\b/g, placeholder: '<PHONE>' },
    // Email
    { name: 'email', re: /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b/g, placeholder: '<EMAIL>' },
    // Saudi national IDs / iqama
    { name: 'national-id', re: /\b[12]\d{9}\b/g, placeholder: '<NATIONAL_ID>' },
    // CR numbers (Saudi)
    { name: 'cr-number', re: /\b\d{10}\b(?=.*?(?:CR|سجل|تجاري))/gi, placeholder: '<CR>' },
    // VAT (15-digit, starts with 3)
    { name: 'vat-saudi', re: /\b3\d{14}\b/g, placeholder: '<VAT>' },
    // IBAN
    { name: 'iban', re: /\bSA\d{22}\b/g, placeholder: '<IBAN>' },
    // Credit card
    { name: 'credit-card', re: /\b(?:\d{4}[\s-]?){3}\d{4}\b/g, placeholder: '<CARD>' },
    // API keys
    { name: 'nvidia-key', re: /nvapi-[A-Za-z0-9_-]{60,90}/g, placeholder: '<API_KEY>' },
    { name: 'openai-key', re: /sk-[A-Za-z0-9]{20,80}/g, placeholder: '<API_KEY>' },
    { name: 'anthropic-key', re: /sk-ant-[A-Za-z0-9_-]{40,120}/g, placeholder: '<API_KEY>' },
    { name: 'google-key', re: /AIza[A-Za-z0-9_-]{35}/g, placeholder: '<API_KEY>' },
    { name: 'aws-access', re: /AKIA[0-9A-Z]{16}/g, placeholder: '<API_KEY>' },
    { name: 'github-pat', re: /ghp_[A-Za-z0-9]{36}/g, placeholder: '<API_KEY>' },
    { name: 'jwt', re: /eyJ[A-Za-z0-9_-]+\.eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+/g, placeholder: '<JWT>' },
    { name: 'bearer', re: /Bearer\s+[A-Za-z0-9_\-.]{20,200}/gi, placeholder: 'Bearer <TOKEN>' },
    // Numeric figures > 4 digits (probably money / IDs)
    { name: 'large-number', re: /\b\d{5,}\b/g, placeholder: '<NUMBER>' },
];
// Common Arabic + English first names that are likely PII when standalone.
// We don't try to be exhaustive — we drop the message-content payload
// entirely and only ship structural facts (length, intent, tools called).
const NAME_HINTS = [
    /\b(?:Mr|Mrs|Ms|Dr|Eng|Prof|H\.E\.|الأستاذ|الدكتور|المهندس|السيد|السيدة|الآنسة|الشيخ)\.?\s+[A-Za-zء-ي]+/g,
];
export function scrubPII(input) {
    if (!input)
        return { scrubbed: input, redactionsByType: {}, totalRedactions: 0 };
    let out = input;
    const counts = {};
    for (const p of PATTERNS) {
        const matches = out.match(p.re);
        if (matches && matches.length > 0) {
            out = out.replace(p.re, p.placeholder);
            counts[p.name] = (counts[p.name] ?? 0) + matches.length;
        }
    }
    for (const re of NAME_HINTS) {
        const matches = out.match(re);
        if (matches && matches.length > 0) {
            out = out.replace(re, '<TITLED_NAME>');
            counts['titled-name'] = (counts['titled-name'] ?? 0) + matches.length;
        }
    }
    return {
        scrubbed: out,
        redactionsByType: counts,
        totalRedactions: Object.values(counts).reduce((a, b) => a + b, 0),
    };
}
export function fingerprintMessage(input) {
    const len = input?.length ?? 0;
    const lengthBucket = len < 50 ? 'short' : len < 300 ? 'medium' : 'long';
    const arChars = (input.match(/[ء-ي]/g) ?? []).length;
    const enChars = (input.match(/[A-Za-z]/g) ?? []).length;
    const language = arChars > enChars * 2 ? 'ar' : enChars > arChars * 2 ? 'en' : 'mixed';
    const scrub = scrubPII(input);
    return {
        length_bucket: lengthBucket,
        language,
        has_question: /[\?؟]/.test(input),
        has_money_mention: /(?:ريال|SAR|\$|USD|دفع|سعر|ثمن|تكلف|price|cost|pay|invoice)/i.test(input),
        has_url: /https?:\/\//.test(input),
        has_phone: (scrub.redactionsByType['phone-saudi-intl'] ?? 0) + (scrub.redactionsByType['phone-saudi-local'] ?? 0) + (scrub.redactionsByType['phone-intl'] ?? 0) > 0,
        has_email: (scrub.redactionsByType['email'] ?? 0) > 0,
        scrubbed_redaction_count: scrub.totalRedactions,
    };
}
//# sourceMappingURL=scrubber.js.map