// Clipboard Poisoning Signal Providers
// Extracts typed features from clipboard write/copy events for poisoning detection.
// Each provider returns { value, metadata? } — no decisions, no severity, no findings.

// ── Crypto address patterns ─────────────────────
const CRYPTO_ADDRESS_PATTERNS = {
  bitcoin:  /^[13][a-km-zA-HJ-NP-Z1-9]{25,34}$/,
  ethereum: /^0x[a-fA-F0-9]{40}$/,
  litecoin: /^[LM3][a-km-zA-HJ-NP-Z1-9]{26,33}$/,
  dogecoin: /^D{1}[5-9A-HJ-NP-U]{1}[1-9A-HJ-NP-Za-km-z]{32}$/,
  monero:   /^4[0-9AB][1-9A-HJ-NP-Za-km-z]{93}$/,
};

// ── Dangerous pastejacking commands ─────────────
const DANGEROUS_PASTE_PATTERNS = [
  /curl.*\|.*(?:ba)?sh/i,
  /wget.*\|.*(?:ba)?sh/i,
  /sudo\s+/i,
  /rm\s+-rf/i,
  /chmod\s+/i,
  /eval\s*\(/i,
  /exec\s*\(/i,
  /powershell/i,
  /cmd\.exe/i,
];

// ── Sensitive data patterns ─────────────────────
const SENSITIVE_DATA_PATTERNS = [
  { pattern: /\b\d{16}\b/, type: 'credit-card-number' },
  { pattern: /\b\d{3}-\d{2}-\d{4}\b/, type: 'ssn' },
  { pattern: /password/i, type: 'password-text' },
  { pattern: /api[_-]?key/i, type: 'api-key' },
  { pattern: /bearer\s+[a-zA-Z0-9_-]+/i, type: 'bearer-token' },
];

// ── Command injection patterns ──────────────────
const COMMAND_INJECTION_PATTERNS = [
  /curl.*\|.*bash/i,
  /wget.*\|.*sh/i,
  /;.*rm\s+-rf/i,
  /&&.*rm\s+-rf/i,
  /sudo\s+/i,
  /chmod\s+\+x/i,
  /eval\s*\(/i,
  /exec\s*\(/i,
  /powershell.*-e[nc]*/i,
  /cmd\.exe.*\/c/i,
];

/**
 * Detect if a value matches a crypto address pattern.
 * Returns the crypto type or null.
 */
function _detectCryptoType(text) {
  if (!text) return null;
  const trimmed = text.trim();
  for (const [type, pattern] of Object.entries(CRYPTO_ADDRESS_PATTERNS)) {
    if (pattern.test(trimmed)) return type;
  }
  return null;
}

/**
 * Register all clipboard-poisoning signal providers on a SignalProviderRegistry.
 * @param {import('../../core/signal-provider.js').SignalProviderRegistry} registry
 */
export function registerClipboardPoisoningSignals(registry) {

  // ── clipboard.crypto_swap_detected ────────────
  registry.register('clipboard', 'crypto_swap_detected', (target) => {
    const writes = target.clipboardWrites || [];
    if (writes.length === 0) return { value: false };

    for (const write of writes) {
      if (!write.originalText || !write.newText || write.originalText === write.newText) continue;

      const origType = _detectCryptoType(write.originalText);
      const newType = _detectCryptoType(write.newText);

      if (origType && newType && origType === newType) {
        return {
          value: true,
          metadata: {
            cryptoType: origType,
            originalAddress: write.originalText,
            maliciousAddress: write.newText,
          },
        };
      }
    }
    return { value: false };
  }, { returnType: 'boolean', scope: 'tab', description: 'Crypto address swap detected in clipboard' });

  // ── clipboard.pastejack_detected ──────────────
  registry.register('clipboard', 'pastejack_detected', (target) => {
    const copyEvents = target.copyEvents || [];
    if (copyEvents.length === 0) return { value: false };

    for (const evt of copyEvents) {
      if (evt.userSelected && evt.pageModified && evt.userSelected !== evt.pageModified) {
        const hasDangerous = DANGEROUS_PASTE_PATTERNS.some(p => p.test(evt.pageModified));
        return {
          value: true,
          metadata: {
            hasDangerousCommand: hasDangerous,
            modifiedPreview: evt.pageModified.substring(0, 80),
          },
        };
      }
    }
    return { value: false };
  }, { returnType: 'boolean', scope: 'tab', description: 'Pastejacking detected — copy event content modified' });

  // ── clipboard.unauthorized_write_count ────────
  registry.register('clipboard', 'unauthorized_write_count', (target) => {
    const writes = target.clipboardWrites || [];
    const hasPermission = target.permissions?.hasClipboardPermission || false;
    if (hasPermission || writes.length === 0) return { value: 0 };
    return {
      value: writes.length,
      metadata: { hasPermission: false },
    };
  }, { returnType: 'number', scope: 'tab', description: 'Number of clipboard writes without permission' });

  // ── clipboard.read_count ──────────────────────
  registry.register('clipboard', 'read_count', (target) => {
    return { value: target.clipboardReadCount || 0 };
  }, { returnType: 'number', scope: 'tab', description: 'Number of clipboard reads by the page' });

  // ── clipboard.has_sensitive_data_write ─────────
  registry.register('clipboard', 'has_sensitive_data_write', (target) => {
    const writes = target.clipboardWrites || [];
    if (writes.length === 0) return { value: false };

    for (const write of writes) {
      if (!write.newText) continue;
      for (const { pattern, type } of SENSITIVE_DATA_PATTERNS) {
        if (pattern.test(write.newText)) {
          return { value: true, metadata: { dataType: type } };
        }
      }
    }
    return { value: false };
  }, { returnType: 'boolean', scope: 'tab', description: 'Sensitive data detected in clipboard writes' });

  // ── clipboard.has_command_injection ────────────
  registry.register('clipboard', 'has_command_injection', (target) => {
    const copyEvents = target.copyEvents || [];
    if (copyEvents.length === 0) return { value: false };

    for (const evt of copyEvents) {
      if (!evt.pageModified) continue;
      if (COMMAND_INJECTION_PATTERNS.some(p => p.test(evt.pageModified))) {
        return {
          value: true,
          metadata: { commandPreview: evt.pageModified.substring(0, 80) },
        };
      }
    }
    return { value: false };
  }, { returnType: 'boolean', scope: 'tab', description: 'Malicious command injected into clipboard via copy event' });
}
