import { existsSync, readFileSync } from 'node:fs';
import { dirname, join } from 'node:path';
import { fileURLToPath } from 'node:url';
import { describe, expect, it } from 'vitest';
import { Parser } from 'n3';
import { parseRdf } from '../src/rdf-parser.js';
import { batchEntityQuads } from '../src/batching.js';

const __dirname = dirname(fileURLToPath(import.meta.url));
const FINDINGS_FILE = join(__dirname, '..', '..', '..', 'tmp', 'findings.synthetic.nt');

function serializeQuadsToNQuads(batch: Array<{ subject: string; predicate: string; object: string; graph: string }>): string {
  return batch
    .map((q) => `<${q.subject}> <${q.predicate}> ${q.object.startsWith('"') ? q.object : `<${q.object}>`} <${q.graph}> .`)
    .join('\n');
}

describe.skipIf(!existsSync(FINDINGS_FILE))('synthetic findings workspace serialization regression', () => {
  it('serializes every staged workspace batch for the synthetic findings file without parser errors', async () => {
    const raw = readFileSync(FINDINGS_FILE, 'utf-8');
    const quads = await parseRdf(raw, 'ntriples', 'did:dkg:context-graph:music-social');

    const batches = batchEntityQuads(quads, {
      maxBatchQuads: 500,
      maxBatchBytes: 450 * 1024,
      estimateBatchBytes: (batch) => new TextEncoder().encode(JSON.stringify({ contextGraphId: 'music-social', quads: batch })).length,
      splitOversizedEntities: true,
    });

    expect(batches.length).toBeGreaterThan(1);

    const parser = new Parser({ format: 'N-Quads' });
    for (const [index, batch] of batches.entries()) {
      const nquads = serializeQuadsToNQuads(batch);
      expect(() => parser.parse(nquads)).not.toThrow();
      if ((index + 1) % 100 === 0) {
        console.log(`Validated batch ${index + 1}/${batches.length}`);
      }
    }
  }, 300000);
});
