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

const root = resolve(new URL('..', import.meta.url).pathname)
const oracle = JSON.parse(await readFile(resolve(root, 'config/freecad-sketcher-editor-oracle.json'), 'utf8'))
if (oracle.schemaVersion !== 1 || oracle.baselineId !== 'freecad-1.1.1-sketcher-editor-oracle' || oracle.freecadVersion !== '1.1.1' || oracle.gitCommit !== '0108fd4b4850cc46e625b60e53cea7a7bbe69f8d' || oracle.tolerance !== 1e-7 || oracle.status !== 'pass' || oracle.summary?.cases !== 7 || oracle.summary?.passed !== 7) throw new Error('FreeCAD Sketcher editor oracle baseline is invalid.')
const fixture = (id) => {
  const result = oracle.cases?.find((entry) => entry.id === id)
  if (!result?.passed) throw new Error(`FreeCAD Sketcher editor fixture ${id} is missing or failed.`)
  return result
}
const pointMatches = (actual, expected) => Array.isArray(actual) && actual.length === 2 && Math.abs(actual[0] - expected[0]) <= oracle.tolerance && Math.abs(actual[1] - expected[1]) <= oracle.tolerance
const drag = fixture('drag-horizontal')
if (drag.solveStatus !== 0 || !pointMatches(drag.final.geometry?.[0]?.start, [0, 2]) || !pointMatches(drag.final.geometry?.[0]?.end, [8, 2]) || JSON.stringify(drag.final.constraintTypes) !== '["Horizontal"]') throw new Error('FreeCAD Sketcher drag fixture is invalid.')
const split = fixture('split-line')
if (split.final.geometry?.length !== 2 || !pointMatches(split.final.geometry[0].end, [4, 0]) || !pointMatches(split.final.geometry[1].start, [4, 0]) || JSON.stringify(split.final.construction) !== '[true,true]' || JSON.stringify(split.final.constraintTypes) !== '["Coincident"]') throw new Error('FreeCAD Sketcher split fixture is invalid.')
const extend = fixture('extend-line')
if (!pointMatches(extend.final.geometry?.[0]?.end, [15, 0])) throw new Error('FreeCAD Sketcher extend fixture is invalid.')
const trim = fixture('trim-at-intersection')
if (!pointMatches(trim.final.geometry?.[0]?.end, [7, 0]) || JSON.stringify(trim.final.constraintTypes) !== '["PointOnObject"]') throw new Error('FreeCAD Sketcher trim fixture is invalid.')
const construction = fixture('toggle-construction')
if (JSON.stringify(construction.final.construction) !== '[true]') throw new Error('FreeCAD Sketcher construction fixture is invalid.')
const transaction = fixture('transaction-undo-redo')
if (!pointMatches(transaction.committedEnd, [8, 0]) || !pointMatches(transaction.undoneEnd, [5, 0]) || !pointMatches(transaction.redoneEnd, [8, 0])) throw new Error('FreeCAD Sketcher transaction fixture is invalid.')
const autoConstraint = fixture('auto-constraint')
if (autoConstraint.solveStatus !== 0 || JSON.stringify(autoConstraint.final.constraintTypes) !== '["Coincident","Horizontal"]' || !pointMatches(autoConstraint.final.geometry?.[0]?.end, [5, 0]) || !pointMatches(autoConstraint.final.geometry?.[1]?.start, [5, 0])) throw new Error('FreeCAD Sketcher autoconstraint fixture is invalid.')

const chrome = JSON.parse(await readFile(resolve(root, 'config/chrome-sketcher-editor-verification.json'), 'utf8'))
const operations = chrome.operations ?? {}
const interactions = chrome.interactions ?? {}
if (chrome.status !== 'pass' || operations.drag?.start?.x !== drag.final.geometry[0].start[0] || operations.drag?.start?.y !== drag.final.geometry[0].start[1] || operations.drag?.end?.x !== drag.final.geometry[0].end[0] || operations.drag?.end?.y !== drag.final.geometry[0].end[1]) throw new Error('Chrome drag result does not match FreeCAD.')
if (JSON.stringify(operations.split?.constraintTypes) !== '["coincident"]' || operations.split?.endpoints?.[0]?.[1]?.x !== split.final.geometry[0].end[0] || operations.split?.endpoints?.[1]?.[0]?.x !== split.final.geometry[1].start[0]) throw new Error('Chrome split result does not match FreeCAD.')
if (operations.extend?.end?.x !== extend.final.geometry[0].end[0] || operations.trim?.end?.x !== trim.final.geometry[0].end[0] || JSON.stringify(operations.trim?.constraintTypes) !== '["pointOnObject"]' || operations.construction?.enabled !== true) throw new Error('Chrome edit results do not match FreeCAD.')
if (JSON.stringify(operations.autoConstraint?.suggestionReasons) !== '["coincident","horizontal"]' || interactions.end?.x !== transaction.redoneEnd[0] || interactions.nativeEvents?.pointer < 2 || interactions.nativeEvents?.keyboard < 3 || interactions.undone !== 1 || interactions.redone !== 1) throw new Error('Chrome task lifecycle does not match the FreeCAD oracle.')
console.log(JSON.stringify({ status: 'freecad-sketcher-editor-oracle-pass', baselineId: oracle.baselineId, freecadVersion: oracle.freecadVersion, summary: oracle.summary, chrome: { operations: Object.keys(operations), interactions } }, null, 2))
