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-property-acceleration-mutation.json'), 'utf8'))
const fail = (message) => { throw new Error(`FreeCAD PropertyAcceleration mutation check failed: ${message}`) }
if (report.schemaVersion !== 1 || report.status !== 'pass' || report.baselineId !== 'freecad-1.1.1-property-acceleration-mutation' || report.freecadVersion !== '1.1.1' || report.gitCommit !== '0108fd4b4850cc46e625b60e53cea7a7bbe69f8d') fail('baseline is invalid')
if (report.object?.name !== 'AccelerationProbe' || report.object.typeId !== 'Robot::TrajectoryDressUpObject' || report.property?.name !== 'Acceleration' || report.property.typeId !== 'App::PropertyAcceleration') fail('native object/property identity changed')
if (!(report.recompute?.initial > 0) || !(report.recompute.edit > 0) || !(report.recompute.restore > 0)) fail('initial, edit and restore were not recomputed')
if (report.touchedAfterEdit?.value?.numeric !== 500 || JSON.stringify(report.touchedAfterEdit.objectState) !== '["Touched"]' || report.touchedAfterEdit.mustExecute !== false) fail('edit did not preserve the native touched/MustExecute state before recompute')
const expectedValues = [['before', 1000], ['edited', 500], ['restored', 1000]]
for (const [phase, expected] of expectedValues) {
  const snapshot = report[phase]
  if (snapshot?.value?.numeric !== expected || typeof snapshot.value.unit !== 'string' || !snapshot.value.unit.includes('mm/s^2') || JSON.stringify(snapshot.propertyStatus) !== '[]' || JSON.stringify(snapshot.editorMode) !== '[]' || snapshot.source?.name !== 'SourceTrajectory' || snapshot.source.typeId !== 'Robot::TrajectoryObject' || snapshot.useAcceleration !== true || snapshot.shape?.applicable !== false || JSON.stringify(snapshot.objectState) !== '["Up-to-date"]' || snapshot.statusString !== 'Valid' || snapshot.mustExecute !== false) fail(`${phase} native semantic state is invalid`)
  if (snapshot.trajectory?.waypointCount !== 2 || snapshot.trajectory.waypoints?.length !== 2 || snapshot.trajectory.waypoints.some((waypoint) => waypoint.acceleration !== expected)) fail(`${phase} waypoint acceleration semantics are invalid`)
}
if (report.before.trajectory.contentSha256 === report.edited.trajectory.contentSha256 || report.before.trajectory.contentSha256 !== report.restored.trajectory.contentSha256) fail('trajectory content did not change and restore exactly')
if (report.source?.preserved !== true || JSON.stringify(report.source.before) !== JSON.stringify(report.source.edited) || JSON.stringify(report.source.before) !== JSON.stringify(report.source.restored)) fail('source trajectory changed during dress-up mutation')
if (report.document?.objectsPreserved !== true || JSON.stringify(report.document.objectsBefore) !== JSON.stringify(report.document.objectsRestored) || report.document.objectsBefore?.length !== 2) fail('mutation polluted the document object set')
if (report.classification?.propertyChanged !== true || report.classification.trajectoryChanged !== true || report.classification.propertyRestored !== true || report.classification.trajectoryRestored !== true || report.classification.semanticStateRestored !== true || report.classification.geometry !== 'not-applicable-no-shape-property') fail('mutation/restore classification is incomplete')
console.log(JSON.stringify({ status: 'freecad-property-acceleration-mutation-pass', recompute: report.recompute, values: Object.fromEntries(expectedValues.map(([phase]) => [phase, report[phase].value.numeric])), waypointAccelerations: Object.fromEntries(expectedValues.map(([phase]) => [phase, report[phase].trajectory.waypoints.map((waypoint) => waypoint.acceleration)])), sourcePreserved: report.source.preserved, semanticStateRestored: report.classification.semanticStateRestored, geometry: report.classification.geometry }, null, 2))
