import { describe, it, expect } from 'vitest';
import { OutboundAttachmentCollector } from './attachments.js';

describe('OutboundAttachmentCollector', () => {
  it('starts with zero count', () => {
    const collector = new OutboundAttachmentCollector();
    expect(collector.count).toBe(0);
  });

  it('push increments count', () => {
    const collector = new OutboundAttachmentCollector();
    collector.push({ mimeType: 'image/png', data: 'abc123' });
    expect(collector.count).toBe(1);

    collector.push({ mimeType: 'application/pdf', url: 'https://example.com/doc.pdf' });
    expect(collector.count).toBe(2);
  });

  it('drain returns all queued attachments', () => {
    const collector = new OutboundAttachmentCollector();
    collector.push({ mimeType: 'image/png', data: 'abc123', filename: 'photo.png' });
    collector.push({ mimeType: 'audio/ogg', url: 'https://example.com/audio.ogg' });

    const drained = collector.drain();
    expect(drained).toHaveLength(2);
    expect(drained[0]).toEqual({
      mimeType: 'image/png',
      data: 'abc123',
      filename: 'photo.png',
    });
    expect(drained[1]).toEqual({
      mimeType: 'audio/ogg',
      url: 'https://example.com/audio.ogg',
    });
  });

  it('drain clears the queue', () => {
    const collector = new OutboundAttachmentCollector();
    collector.push({ mimeType: 'image/png', data: 'abc123' });
    expect(collector.count).toBe(1);

    collector.drain();
    expect(collector.count).toBe(0);
  });

  it('drain returns empty array when nothing queued', () => {
    const collector = new OutboundAttachmentCollector();
    const drained = collector.drain();
    expect(drained).toEqual([]);
  });

  it('drain returns a copy, not the internal array', () => {
    const collector = new OutboundAttachmentCollector();
    collector.push({ mimeType: 'image/png', data: 'abc123' });
    const first = collector.drain();
    const second = collector.drain();

    // First drain got the item, second drain is empty
    expect(first).toHaveLength(1);
    expect(second).toHaveLength(0);

    // Mutating the returned array doesn't affect the collector
    first.push({ mimeType: 'image/gif', data: 'xyz' });
    expect(collector.count).toBe(0);
  });

  it('can push and drain multiple cycles', () => {
    const collector = new OutboundAttachmentCollector();

    // First cycle
    collector.push({ mimeType: 'image/png', data: 'cycle1' });
    expect(collector.drain()).toHaveLength(1);
    expect(collector.count).toBe(0);

    // Second cycle
    collector.push({ mimeType: 'image/jpeg', data: 'cycle2a' });
    collector.push({ mimeType: 'image/gif', data: 'cycle2b' });
    const second = collector.drain();
    expect(second).toHaveLength(2);
    expect(second[0].data).toBe('cycle2a');
    expect(second[1].data).toBe('cycle2b');
  });
});
