/**
 * PromQL query validation utilities
 * Prevents injection vulnerabilities in Prometheus queries
 */

/**
 * Validates PromQL query string to prevent injection attacks
 * Allows only safe metric names, labels, operators, and functions
 *
 * @param query - The PromQL query to validate
 * @throws Error if query contains unsafe characters or functions
 */
export function validatePromQLQuery(query: string): void {
  if (!query || typeof query !== 'string') {
    throw new Error('Invalid PromQL query: query must be a non-empty string');
  }

  // Block dangerous characters that could enable injection
  const dangerousChars = [';', '&', '|', '`', '$', '\\'];
  for (const char of dangerousChars) {
    if (query.includes(char)) {
      throw new Error(`Invalid PromQL query: unsafe character '${char}' detected`);
    }
  }

  // Block dangerous PromQL functions that could enable resource exhaustion
  const dangerousFunctions = [
    'absent_over_time', // Can cause expensive queries
    'predict_linear', // Computationally expensive
    'deriv', // Can be expensive on large datasets
    'holt_winters', // Computationally expensive
  ];

  const lowerQuery = query.toLowerCase();
  for (const fn of dangerousFunctions) {
    if (lowerQuery.includes(fn)) {
      throw new Error(`Invalid PromQL query: dangerous function '${fn}' detected`);
    }
  }

  // Basic structure validation: queries should contain alphanumeric, underscores, colons, and safe operators
  // This is a permissive check to catch obvious malicious input
  const safePattern = /^[a-zA-Z0-9_:(){}\[\],.+\-*/<>=!~\s"'%]+$/;
  if (!safePattern.test(query)) {
    throw new Error('Invalid PromQL query: contains unsafe characters');
  }
}

/**
 * Validates an array of PromQL queries
 *
 * @param queries - Array of PromQL queries to validate
 * @throws Error if any query is invalid
 */
export function validatePromQLQueries(queries: string[]): void {
  if (!Array.isArray(queries)) {
    throw new Error('Invalid input: queries must be an array');
  }

  for (let i = 0; i < queries.length; i++) {
    try {
      validatePromQLQuery(queries[i]);
    } catch (error) {
      throw new Error(`Query #${i + 1} validation failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
    }
  }
}
