/**
 * CDN Pipeline module — unit tests.
 */

import { describe, it, expect } from 'vitest';
import { UploadAssetSchema, PurgeRequestSchema, UpdateOriginConfigSchema } from './types.js';

describe('UploadAssetSchema', () => {
  it('validates minimal asset', () => {
    const result = UploadAssetSchema.safeParse({
      originalName: 'hero.png',
      mimeType: 'image/png',
      sizeBytes: 1024,
      contentHash: 'abc123def456',
      blobPath: 'cdn-assets/hero.png',
    });
    expect(result.success).toBe(true);
    if (result.success) {
      expect(result.data.category).toBe('other');
      expect(result.data.isPublic).toBe(true);
    }
  });

  it('validates with all fields', () => {
    const result = UploadAssetSchema.safeParse({
      originalName: 'logo.svg',
      mimeType: 'image/svg+xml',
      sizeBytes: 2048,
      contentHash: 'deadbeef01234567',
      blobPath: 'cdn-assets/logo.svg',
      category: 'image',
      isPublic: false,
      metadata: { width: 200, height: 200 },
    });
    expect(result.success).toBe(true);
    if (result.success) {
      expect(result.data.category).toBe('image');
      expect(result.data.isPublic).toBe(false);
    }
  });

  it('rejects empty originalName', () => {
    expect(
      UploadAssetSchema.safeParse({
        originalName: '',
        mimeType: 'image/png',
        sizeBytes: 1024,
        contentHash: 'abc123de',
        blobPath: 'test.png',
      }).success
    ).toBe(false);
  });

  it('rejects oversized file', () => {
    expect(
      UploadAssetSchema.safeParse({
        originalName: 'big.bin',
        mimeType: 'application/octet-stream',
        sizeBytes: 200 * 1024 * 1024, // 200 MB
        contentHash: 'abc123de',
        blobPath: 'big.bin',
      }).success
    ).toBe(false);
  });

  it('rejects invalid category', () => {
    expect(
      UploadAssetSchema.safeParse({
        originalName: 'file.txt',
        mimeType: 'text/plain',
        sizeBytes: 100,
        contentHash: 'abc123de',
        blobPath: 'file.txt',
        category: 'invalid_category',
      }).success
    ).toBe(false);
  });

  it('rejects short contentHash', () => {
    expect(
      UploadAssetSchema.safeParse({
        originalName: 'file.txt',
        mimeType: 'text/plain',
        sizeBytes: 100,
        contentHash: 'abc', // too short
        blobPath: 'file.txt',
      }).success
    ).toBe(false);
  });
});

describe('PurgeRequestSchema', () => {
  it('validates single pattern', () => {
    const result = PurgeRequestSchema.safeParse({ patterns: ['/assets/img/*'] });
    expect(result.success).toBe(true);
  });

  it('validates multiple patterns', () => {
    const result = PurgeRequestSchema.safeParse({
      patterns: ['/assets/img/*', '/assets/css/*', '/favicon.ico'],
    });
    expect(result.success).toBe(true);
    if (result.success) expect(result.data.patterns).toHaveLength(3);
  });

  it('rejects empty patterns array', () => {
    expect(PurgeRequestSchema.safeParse({ patterns: [] }).success).toBe(false);
  });

  it('rejects too many patterns', () => {
    const patterns = Array.from({ length: 51 }, (_, i) => `/path${i}`);
    expect(PurgeRequestSchema.safeParse({ patterns }).success).toBe(false);
  });
});

describe('UpdateOriginConfigSchema', () => {
  it('validates partial update', () => {
    const result = UpdateOriginConfigSchema.safeParse({
      defaultCacheTtlSeconds: 3600,
      brotliEnabled: false,
    });
    expect(result.success).toBe(true);
  });

  it('validates CORS origins', () => {
    const result = UpdateOriginConfigSchema.safeParse({
      corsOrigins: ['https://app.example.com', '*'],
    });
    expect(result.success).toBe(true);
  });

  it('validates category TTL overrides', () => {
    const result = UpdateOriginConfigSchema.safeParse({
      categoryTtlOverrides: { image: 604800, font: 2592000 },
    });
    expect(result.success).toBe(true);
  });

  it('rejects negative cache TTL', () => {
    expect(UpdateOriginConfigSchema.safeParse({ defaultCacheTtlSeconds: -1 }).success).toBe(false);
  });

  it('validates null customDomain (to clear)', () => {
    const result = UpdateOriginConfigSchema.safeParse({ customDomain: null });
    expect(result.success).toBe(true);
  });
});
