/**
 * Data Sanitization Utility
 * CWE-532: Prevents logging of sensitive data
 * Ensures compliance with HIPAA, PCI, SOX regulations
 */

const SENSITIVE_FIELDS = [
  'password',
  'newPassword',
  'oldPassword',
  'currentPassword',
  'confirmPassword',
  'token',
  'accessToken',
  'refreshToken',
  'jwt',
  'secret',
  'apiKey',
  'api_key',
  'privateKey',
  'private_key',
  'two_factor_secret',
  'twoFactorSecret',
  'backup_codes',
  'backupCodes',
  'creditCard',
  'credit_card',
  'cvv',
  'ssn',
  'social_security',
  'pin',
  'authCode',
  'auth_code'
];

/**
 * Sanitize object by removing or masking sensitive fields
 * @param {Object} data - Object to sanitize
 * @param {Array} additionalFields - Additional fields to sanitize
 * @returns {Object} Sanitized object
 */
function sanitizeForLogging(data, additionalFields = []) {
  if (!data || typeof data !== 'object') {
    return data;
  }

  const sensitiveFields = [...SENSITIVE_FIELDS, ...additionalFields];
  const sanitized = Array.isArray(data) ? [] : {};

  for (const [key, value] of Object.entries(data)) {
    const lowerKey = key.toLowerCase();
    const isSensitive = sensitiveFields.some(field => 
      lowerKey.includes(field.toLowerCase())
    );

    if (isSensitive) {
      sanitized[key] = '[REDACTED]';
    } else if (value && typeof value === 'object') {
      sanitized[key] = sanitizeForLogging(value, additionalFields);
    } else {
      sanitized[key] = value;
    }
  }

  return sanitized;
}

/**
 * Sanitize user object for export (remove password hash)
 * @param {Object} user - User object from database
 * @returns {Object} Sanitized user object
 */
function sanitizeUserForExport(user) {
  if (!user) return user;

  const sanitized = { ...user };
  delete sanitized.password;
  delete sanitized.two_factor_secret;
  delete sanitized.backup_codes;
  
  return sanitized;
}

/**
 * Sanitize user array for export
 * @param {Array} users - Array of user objects
 * @returns {Array} Sanitized user array
 */
function sanitizeUsersForExport(users) {
  if (!Array.isArray(users)) return users;
  return users.map(user => sanitizeUserForExport(user));
}

/**
 * Mask token for logging (show only last 8 characters)
 * @param {String} token - Token to mask
 * @returns {String} Masked token
 */
function maskToken(token) {
  if (!token || typeof token !== 'string') return '[INVALID_TOKEN]';
  if (token.length <= 8) return '***';
  return '...' + token.slice(-8);
}

/**
 * Mask email for logging (show only domain)
 * @param {String} email - Email to mask
 * @returns {String} Masked email
 */
function maskEmail(email) {
  if (!email || typeof email !== 'string') return '[INVALID_EMAIL]';
  const parts = email.split('@');
  if (parts.length !== 2) return '[INVALID_EMAIL]';
  return `***@${parts[1]}`;
}

/**
 * Sanitize request body for logging
 * @param {Object} body - Request body
 * @returns {Object} Sanitized body
 */
function sanitizeRequestBody(body) {
  return sanitizeForLogging(body);
}

/**
 * Create safe metadata object for audit logging
 * Ensures no sensitive data is included in audit logs
 * @param {Object} data - Data to include in audit metadata
 * @returns {Object} Safe metadata object
 */
function createSafeAuditMetadata(data) {
  const safe = sanitizeForLogging(data);
  
  // Specifically handle common patterns
  if (safe.user && typeof safe.user === 'object') {
    safe.user = sanitizeUserForExport(safe.user);
  }
  
  if (safe.changes && typeof safe.changes === 'object') {
    safe.changes = sanitizeForLogging(safe.changes);
  }
  
  return safe;
}

module.exports = {
  sanitizeForLogging,
  sanitizeUserForExport,
  sanitizeUsersForExport,
  maskToken,
  maskEmail,
  sanitizeRequestBody,
  createSafeAuditMetadata,
  SENSITIVE_FIELDS
};
