const { validateS3Keys } = require('../../../utils/s3KeyValidator');

describe('S3 Key Validator', () => {
  describe('validateS3Keys', () => {
    const validUuid1 = '550e8400-e29b-41d4-a716-446655440000';
    const validUuid2 = '660e8400-e29b-41d4-a716-446655440001';

    test('should accept valid arrays of keys', () => {
      const keys = [
        `items/${validUuid1}.jpg`,
        `items/${validUuid2}.png`,
      ];
      expect(validateS3Keys(keys, 'items')).toEqual({ valid: true });
    });

    test('should accept valid keys for each folder', () => {
      expect(validateS3Keys([`profiles/${validUuid1}.jpg`], 'profiles')).toEqual({ valid: true });
      expect(validateS3Keys([`items/${validUuid1}.png`], 'items')).toEqual({ valid: true });
      expect(validateS3Keys([`messages/${validUuid1}.gif`], 'messages')).toEqual({ valid: true });
      expect(validateS3Keys([`forum/${validUuid1}.webp`], 'forum')).toEqual({ valid: true });
      expect(validateS3Keys([`condition-checks/${validUuid1}.jpeg`], 'condition-checks')).toEqual({ valid: true });
    });

    test('should accept different valid extensions', () => {
      const extensions = ['jpg', 'jpeg', 'png', 'gif', 'webp'];
      for (const ext of extensions) {
        expect(validateS3Keys([`items/${validUuid1}.${ext}`], 'items')).toEqual({ valid: true });
      }
    });

    test('should be case-insensitive for extensions', () => {
      expect(validateS3Keys([`items/${validUuid1}.JPG`], 'items')).toEqual({ valid: true });
      expect(validateS3Keys([`items/${validUuid1}.PNG`], 'items')).toEqual({ valid: true });
    });

    test('should accept empty arrays', () => {
      expect(validateS3Keys([], 'items')).toEqual({ valid: true });
    });

    test('should reject non-array input', () => {
      const result = validateS3Keys('not-an-array', 'items');
      expect(result.valid).toBe(false);
      expect(result.error).toBe('Keys must be an array');
    });

    test('should reject arrays exceeding maxKeys', () => {
      const keys = Array(6).fill(`items/${validUuid1}.jpg`);
      const result = validateS3Keys(keys, 'items', { maxKeys: 5 });
      expect(result.valid).toBe(false);
      expect(result.error).toContain('Maximum 5 keys allowed');
    });

    test('should reject duplicate keys', () => {
      const keys = [
        `items/${validUuid1}.jpg`,
        `items/${validUuid1}.jpg`,
      ];
      const result = validateS3Keys(keys, 'items');
      expect(result.valid).toBe(false);
      expect(result.error).toBe('Duplicate keys not allowed');
    });

    test('should reject keys with wrong folder prefix', () => {
      const result = validateS3Keys([`profiles/${validUuid1}.jpg`], 'items');
      expect(result.valid).toBe(false);
      expect(result.invalidKeys).toHaveLength(1);
    });

    test('should reject invalid UUID format', () => {
      const result = validateS3Keys(['items/invalid-uuid.jpg'], 'items');
      expect(result.valid).toBe(false);
    });

    test('should reject non-image extensions', () => {
      const result = validateS3Keys([`items/${validUuid1}.exe`], 'items');
      expect(result.valid).toBe(false);
    });

    test('should reject path traversal attempts', () => {
      const result = validateS3Keys([`../items/${validUuid1}.jpg`], 'items');
      expect(result.valid).toBe(false);
    });

    test('should reject empty or null keys in array', () => {
      expect(validateS3Keys([''], 'items').valid).toBe(false);
      expect(validateS3Keys([null], 'items').valid).toBe(false);
    });

    test('should reject invalid folder names', () => {
      const result = validateS3Keys([`items/${validUuid1}.jpg`], 'invalid-folder');
      expect(result.valid).toBe(false);
    });

    test('should return invalid keys in error response', () => {
      const keys = [
        `items/${validUuid1}.jpg`,
        'invalid-key.jpg',
        `items/${validUuid2}.exe`,
      ];
      const result = validateS3Keys(keys, 'items');
      expect(result.valid).toBe(false);
      expect(result.invalidKeys).toHaveLength(2);
    });

    test('should use default maxKeys of 20', () => {
      const keys = Array(20).fill(0).map((_, i) =>
        `items/550e8400-e29b-41d4-a716-44665544${String(i).padStart(4, '0')}.jpg`
      );
      expect(validateS3Keys(keys, 'items')).toEqual({ valid: true });
    });
  });
});
