import { readFile } from 'node:fs/promises'
import { resolve } from 'node:path'

const root = resolve(new URL('..', import.meta.url).pathname)
const report = JSON.parse(await readFile(resolve(root, 'config/freecad-part-builders-oracle.json'), 'utf8'))
const fail = (message) => { throw new Error(`FreeCAD Part builders oracle: ${message}`) }
const commit = '0108fd4b4850cc46e625b60e53cea7a7bbe69f8d'
const expectedSuccess = new Map([
  ['Part::Extrusion', { id: 'part-extrusion-success', shapeType: 'Solid', solids: 1, faces: 6, edges: 12, vertices: 8, volume: 30 }],
  ['Part::Revolution', { id: 'part-revolution-success', shapeType: 'Solid', solids: 1, faces: 4, edges: 6, vertices: 4, volume: 75.398223686155 }],
  ['Part::Loft', { id: 'part-loft-success', shapeType: 'Solid', solids: 1, faces: 6, edges: 12, vertices: 8, volume: 46.666666666666664 }],
  ['Part::Sweep', { id: 'part-sweep-success', shapeType: 'Solid', solids: 1, faces: 6, edges: 12, vertices: 8, volume: 24 }],
  ['Part::Fillet', { id: 'part-fillet-success', shapeType: 'Compound', solids: 1, faces: 7, edges: 15, vertices: 10, volume: 478.7123889803846 }],
  ['Part::Chamfer', { id: 'part-chamfer-success', shapeType: 'Compound', solids: 1, faces: 7, edges: 15, vertices: 10, volume: 477 }],
])
const expectedDiagnostics = new Map([
  ['Part::Extrusion', 'No object linked'],
  ['Part::Revolution', 'No object linked'],
  ['Part::Loft', 'No sections linked.'],
  ['Part::Sweep', 'No sections linked.'],
  ['Part::Fillet', 'No object linked'],
  ['Part::Chamfer', 'No object linked'],
])
if (report.schemaVersion !== 1 || report.baselineId !== 'freecad-1.1.1-part-builders-oracle' || report.freecadVersion !== '1.1.1' || report.gitCommit !== commit || report.status !== 'pass') fail('baseline or status is invalid.')
if (report.summary?.successCases !== 6 || report.summary.successPassed !== 6 || report.summary.failureCases !== 6 || report.summary.failurePassed !== 6 || report.summary.rejected !== 6 || report.summary.acceptedEmpty !== 0) fail('summary is incomplete.')
if (!Array.isArray(report.successCases) || report.successCases.length !== expectedSuccess.size || !Array.isArray(report.failureCases) || report.failureCases.length !== expectedDiagnostics.size) fail('case inventory is incomplete.')
for (const [typeId, expected] of expectedSuccess) {
  const fixture = report.successCases.find((candidate) => candidate.typeId === typeId)
  if (!fixture || fixture.id !== expected.id || fixture.expected !== 'success' || fixture.observed !== 'success' || fixture.passed !== true || fixture.shapeNull !== false || fixture.shapeValid !== true || fixture.statusString !== 'Valid' || !fixture.state?.includes('Up-to-date')) fail(`${typeId} is not valid native success evidence.`)
  for (const field of ['shapeType', 'solids', 'faces', 'edges', 'vertices']) if (fixture[field] !== expected[field]) fail(`${typeId}.${field} drifted from the native oracle.`)
  if (Math.abs(fixture.volume - expected.volume) > 1e-8) fail(`${typeId}.volume drifted from the native oracle.`)
}
for (const [typeId, diagnostic] of expectedDiagnostics) {
  const fixture = report.failureCases.find((candidate) => candidate.typeId === typeId)
  if (!fixture || fixture.inputClass !== 'missing-required-input' || fixture.expected !== 'rejected' || fixture.observed !== 'rejected' || fixture.passed !== true || fixture.shapeNull !== true || fixture.statusString !== diagnostic || !fixture.state?.includes('Invalid')) fail(`${typeId} is not a native rejected failure fixture.`)
}
console.log(JSON.stringify({ status: 'freecad-part-builders-oracle-pass', successCases: report.summary.successCases, failureCases: report.summary.failureCases, rejected: report.summary.rejected, typeIds: [...expectedSuccess.keys()] }, null, 2))
