import { describe, it, expect } from 'vitest';
import { nnunetSourceFilesFromItemsList } from './fromItemsList';

describe('nnunetSourceFilesFromItemsList', () => {
  it('maps a standard Items List into per-series channels with consecutive indices', () => {
    const json = JSON.stringify([
      { name: 'case_00', series: [{ items: 'a/t2.nii.gz' }, { items: 'a/adc.nii.gz' }] },
      { name: 'case_01', series: [{ items: 'b/t2.nii.gz' }, { items: 'b/adc.nii.gz' }] },
    ]);
    const r = nnunetSourceFilesFromItemsList(json, 'nifti', '.nii.gz');
    expect(r.ok).toBe(true);
    expect(r.errors).toEqual([]);
    expect(r.files).toHaveLength(4);
    const c0 = r.files.filter((f) => f.caseId === 'case_00');
    expect(c0.map((f) => f.channelIndex)).toEqual([0, 1]);
    expect(c0[0].filename).toBe('case_00_0000.nii.gz');
    expect(c0.every((f) => f.role === 'image' && f.split === 'train')).toBe(true);
  });

  it('passes the split through to every synthesized file', () => {
    // path must be bucket-relative (bucket/key) — the adapter reuses the shared validator (IL6/C2).
    const json = JSON.stringify([{ name: 'c', series: [{ items: 'bucket/x.nii.gz' }] }]);
    const r = nnunetSourceFilesFromItemsList(json, 'nifti', '.nii.gz', 'test');
    expect(r.ok).toBe(true);
    expect(r.files[0]?.split).toBe('test');
  });

  it('surfaces parser errors and yields NO files on malformed JSON (never half-maps)', () => {
    const r = nnunetSourceFilesFromItemsList('not json', 'nifti', '.nii.gz');
    expect(r.ok).toBe(false);
    expect(r.files).toEqual([]);
    expect(r.errors[0]?.code).toBe('ITEMS_LIST_MALFORMED');
  });

  it('reuses the shared IL3 rule — a NIfTI series given an array of items is rejected, no files', () => {
    const json = JSON.stringify([{ name: 'c', series: [{ items: ['a.nii.gz', 'b.nii.gz'] }] }]);
    const r = nnunetSourceFilesFromItemsList(json, 'nifti', '.nii.gz');
    expect(r.ok).toBe(false);
    expect(r.files).toEqual([]);
    expect(r.errors.some((e) => e.code === 'ENTRY_ITEMS_SHAPE')).toBe(true);
  });
});
