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-sketcher-constraint-oracle.json'), 'utf8'))
const expectedTypes = ['Coincident', 'Horizontal', 'Vertical', 'Parallel', 'Tangent', 'Distance', 'DistanceX', 'DistanceY', 'Angle', 'Perpendicular', 'Radius', 'Equal', 'PointOnObject', 'Symmetric', 'InternalAlignment', 'SnellsLaw', 'Block', 'Diameter', 'Weight']
if (report.schemaVersion !== 1 || report.baselineId !== 'freecad-1.1.1-sketcher-constraint-oracle' || report.freecadVersion !== '1.1.1' || report.gitCommit !== '0108fd4b4850cc46e625b60e53cea7a7bbe69f8d' || report.status !== 'pass' || report.tolerance !== 1e-7) throw new Error('FreeCAD Sketcher constraint oracle baseline is invalid.')
if (report.summary?.constraintTypes !== expectedTypes.length || report.summary?.successCases !== expectedTypes.length || report.summary?.successPassed !== expectedTypes.length || report.summary?.failureCases !== expectedTypes.length || report.summary?.failurePassed !== expectedTypes.length) throw new Error('FreeCAD Sketcher constraint oracle summary is incomplete.')
for (const constraintType of expectedTypes) {
  const success = report.successCases?.find((entry) => entry.constraintType === constraintType)
  const failure = report.failureCases?.find((entry) => entry.constraintType === constraintType)
  if (!success || success.expected !== 'success' || success.observed !== 'success' || success.solveStatus !== 0 || !Number.isFinite(success.degreesOfFreedom) || !Number.isFinite(success.residual) || Math.abs(success.residual) > report.tolerance || success.conflicting?.length || success.redundant?.length || success.malformed?.length) throw new Error(`FreeCAD Sketcher ${constraintType} success fixture is invalid.`)
  if (!failure || failure.expected !== 'failure' || failure.observed !== 'failure') throw new Error(`FreeCAD Sketcher ${constraintType} failure fixture is invalid.`)
}
const reference = report.classificationCases?.find((entry) => entry.id === 'reference-dimension')
const redundant = report.classificationCases?.find((entry) => entry.id === 'redundant-dimension')
const conflicting = report.classificationCases?.find((entry) => entry.id === 'conflicting-dimension')
if (report.summary?.classificationCases !== 3 || report.summary?.classificationPassed !== 3) throw new Error('FreeCAD Sketcher classification oracle summary is incomplete.')
if (reference?.observed !== 'reference' || reference?.solveStatus !== 0 || reference?.degreesOfFreedom !== 3 || reference?.driving !== false || !Number.isFinite(reference?.measuredValue) || Math.abs(reference.measuredValue - reference.inputValue) <= report.tolerance || reference?.conflicting?.length || reference?.redundant?.length || reference?.malformed?.length) throw new Error('FreeCAD Sketcher reference dimension classification is invalid.')
if (redundant?.observed !== 'redundant' || redundant?.solveStatus !== -2 || redundant?.degreesOfFreedom !== 3 || JSON.stringify(redundant?.redundant) !== '[2]' || redundant?.conflicting?.length || redundant?.malformed?.length) throw new Error('FreeCAD Sketcher redundant dimension classification is invalid.')
if (conflicting?.observed !== 'conflicting' || conflicting?.solveStatus !== -3 || conflicting?.degreesOfFreedom !== 3 || JSON.stringify(conflicting?.conflicting) !== '[1,2]' || conflicting?.redundant?.length || conflicting?.malformed?.length) throw new Error('FreeCAD Sketcher conflicting dimension classification is invalid.')
console.log(JSON.stringify({ status: 'freecad-sketcher-constraint-oracle-pass', baselineId: report.baselineId, freecadVersion: report.freecadVersion, gitCommit: report.gitCommit, summary: report.summary }, null, 2))
