/**
 * S3 Key Validation Utility
 * Validates that user-supplied S3 keys match expected formats
 * to prevent IDOR and arbitrary data injection attacks
 */

// UUID v4 regex pattern
const UUID_PATTERN =
  "[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}";

// Allowed image extensions
const ALLOWED_EXTENSIONS = ["jpg", "jpeg", "png", "gif", "webp"];

// Valid S3 folders
const VALID_FOLDERS = [
  "profiles",
  "items",
  "messages",
  "forum",
  "condition-checks",
];

/**
 * Build regex pattern for a specific folder
 * @param {string} folder - The S3 folder name
 * @returns {RegExp}
 */
function buildKeyPattern(folder) {
  const extPattern = ALLOWED_EXTENSIONS.join("|");
  return new RegExp(`^${folder}/${UUID_PATTERN}\\.(${extPattern})$`, "i");
}

/**
 * Validate a single S3 key
 * @param {string} key - The S3 key to validate
 * @param {string} folder - Expected folder (profiles, items, messages, forum, condition-checks)
 * @returns {{ valid: boolean, error?: string }}
 */
function validateS3Key(key, folder) {
  if (!key || typeof key !== "string") {
    return { valid: false, error: "Key must be a non-empty string" };
  }

  if (!VALID_FOLDERS.includes(folder)) {
    return { valid: false, error: `Invalid folder` };
  }

  const pattern = buildKeyPattern(folder);
  if (!pattern.test(key)) {
    return {
      valid: false,
      error: `Invalid key format`,
    };
  }

  return { valid: true };
}

/**
 * Validate an array of S3 keys
 * @param {Array} keys - Array of S3 keys to validate
 * @param {string} folder - Expected folder (profiles, items, messages, forum, condition-checks)
 * @param {Object} options - Validation options
 * @param {number} options.maxKeys - Maximum number of keys allowed
 * @returns {{ valid: boolean, error?: string, invalidKeys?: Array }}
 */
function validateS3Keys(keys, folder, options = {}) {
  const { maxKeys = 20 } = options;

  if (!Array.isArray(keys)) {
    return { valid: false, error: "Keys must be an array" };
  }

  if (keys.length > maxKeys) {
    return { valid: false, error: `Maximum ${maxKeys} keys allowed` };
  }

  if (keys.length === 0) {
    return { valid: true };
  }

  const uniqueKeys = new Set(keys);
  if (uniqueKeys.size !== keys.length) {
    return { valid: false, error: "Duplicate keys not allowed" };
  }

  const invalidKeys = [];
  for (const key of keys) {
    const result = validateS3Key(key, folder);
    if (!result.valid) {
      invalidKeys.push({ key, error: result.error });
    }
  }

  if (invalidKeys.length > 0) {
    return { valid: false, error: "Invalid S3 key format", invalidKeys };
  }

  return { valid: true };
}

module.exports = { validateS3Keys };
