/**
 * Sanitizes user input to prevent prompt injection attacks
 * Strips control characters, limits length, and escapes template injection
 */

/**
 * Strip control characters (0x00-0x1F, 0x7F)
 */
function stripControlChars(str: string): string {
  return str.replace(/[\x00-\x1F\x7F]/g, '');
}

/**
 * Escape template literals to prevent injection
 */
function escapeTemplateLiterals(str: string): string {
  return str
    .replace(/\\/g, '\\\\')  // Escape backslashes first
    .replace(/\$/g, '\\$')   // Escape $ to prevent ${} injection
    .replace(/`/g, '\\`');   // Escape backticks
}

/**
 * Sanitize string input
 */
export function sanitizeInput(
  input: string,
  options: {
    maxLength?: number;
    stripControls?: boolean;
    escapeTemplates?: boolean;
  } = {}
): string {
  if (typeof input !== 'string') {
    return '';
  }

  let sanitized = input;

  // Strip control characters by default
  if (options.stripControls !== false) {
    sanitized = stripControlChars(sanitized);
  }

  // Escape template literals by default
  if (options.escapeTemplates !== false) {
    sanitized = escapeTemplateLiterals(sanitized);
  }

  // Trim whitespace
  sanitized = sanitized.trim();

  // Limit length if specified
  if (options.maxLength && sanitized.length > options.maxLength) {
    sanitized = sanitized.substring(0, options.maxLength);
  }

  return sanitized;
}

/**
 * Sanitize multiple string inputs at once
 */
export function sanitizeInputs(
  inputs: Record<string, string>,
  fieldOptions: Record<string, { maxLength?: number }> = {}
): Record<string, string> {
  const sanitized: Record<string, string> = {};

  for (const [key, value] of Object.entries(inputs)) {
    const options = fieldOptions[key] || {};
    sanitized[key] = sanitizeInput(value, options);
  }

  return sanitized;
}