/**
 * Tests for blob storage schemas.
 */

import { describe, it, expect } from 'vitest';
import {
  GenerateSasSchema,
  ListBlobsSchema,
  DeleteBlobSchema,
  UploadMetadataSchema,
} from './types.js';

describe('GenerateSasSchema', () => {
  it('accepts valid request with defaults', () => {
    const result = GenerateSasSchema.safeParse({
      container: 'audio',
      blobName: 'lysnrai/user123/recording.wav',
    });
    expect(result.success).toBe(true);
    if (result.success) {
      expect(result.data.permissions).toBe('r');
      expect(result.data.expiresInMinutes).toBe(60);
    }
  });

  it('accepts write permissions', () => {
    const result = GenerateSasSchema.safeParse({
      container: 'attachments',
      blobName: 'lysnrai/item123/screenshot.png',
      permissions: 'rw',
      expiresInMinutes: 15,
    });
    expect(result.success).toBe(true);
  });

  it('rejects invalid container', () => {
    const result = GenerateSasSchema.safeParse({
      container: 'nonexistent',
      blobName: 'test.txt',
    });
    expect(result.success).toBe(false);
  });

  it('rejects empty blobName', () => {
    const result = GenerateSasSchema.safeParse({
      container: 'audio',
      blobName: '',
    });
    expect(result.success).toBe(false);
  });

  it('rejects expiry over 24 hours', () => {
    const result = GenerateSasSchema.safeParse({
      container: 'audio',
      blobName: 'test.wav',
      expiresInMinutes: 1441,
    });
    expect(result.success).toBe(false);
  });

  it('accepts all known containers', () => {
    for (const container of [
      'audio',
      'transcripts',
      'attachments',
      'avatars',
      'releases',
      'backups',
    ]) {
      const result = GenerateSasSchema.safeParse({
        container,
        blobName: 'test.bin',
      });
      expect(result.success).toBe(true);
    }
  });
});

describe('ListBlobsSchema', () => {
  it('accepts container with defaults', () => {
    const result = ListBlobsSchema.safeParse({ container: 'audio' });
    expect(result.success).toBe(true);
    if (result.success) {
      expect(result.data.limit).toBe(100);
      expect(result.data.prefix).toBeUndefined();
    }
  });

  it('accepts prefix and custom limit', () => {
    const result = ListBlobsSchema.safeParse({
      container: 'transcripts',
      prefix: 'lysnrai/user123/',
      limit: '50',
    });
    expect(result.success).toBe(true);
    if (result.success) {
      expect(result.data.limit).toBe(50);
      expect(result.data.prefix).toBe('lysnrai/user123/');
    }
  });

  it('rejects limit over 500', () => {
    const result = ListBlobsSchema.safeParse({
      container: 'audio',
      limit: '501',
    });
    expect(result.success).toBe(false);
  });
});

describe('DeleteBlobSchema', () => {
  it('accepts valid delete request', () => {
    const result = DeleteBlobSchema.safeParse({
      container: 'attachments',
      blobName: 'lysnrai/item123/file.pdf',
    });
    expect(result.success).toBe(true);
  });

  it('rejects missing blobName', () => {
    const result = DeleteBlobSchema.safeParse({
      container: 'audio',
    });
    expect(result.success).toBe(false);
  });
});

describe('UploadMetadataSchema', () => {
  it('accepts with defaults', () => {
    const result = UploadMetadataSchema.safeParse({
      container: 'avatars',
      blobName: 'lysnrai/user123/avatar.jpg',
    });
    expect(result.success).toBe(true);
    if (result.success) {
      expect(result.data.contentType).toBe('application/octet-stream');
    }
  });

  it('accepts custom content type and metadata', () => {
    const result = UploadMetadataSchema.safeParse({
      container: 'transcripts',
      blobName: 'lysnrai/user123/transcript.pdf',
      contentType: 'application/pdf',
      metadata: { userId: 'user123', format: 'pdf' },
    });
    expect(result.success).toBe(true);
    if (result.success) {
      expect(result.data.contentType).toBe('application/pdf');
      expect(result.data.metadata?.userId).toBe('user123');
    }
  });
});
