import { isDeepStrictEqual } from 'node:util'
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-colorlist-mutation.json'), 'utf8'))
const fail = (message) => { throw new Error(`FreeCAD PropertyColorList mutation check failed: ${message}`) }
if (report.schemaVersion !== 1 || report.status !== 'pass' || report.baselineId !== 'freecad-1.1.1-property-colorlist-mutation' || report.freecadVersion !== '1.1.1' || report.gitCommit !== '0108fd4b4850cc46e625b60e53cea7a7bbe69f8d' || report.propertyType !== 'App::PropertyColorList' || report.caseCount !== 2 || report.cases?.length !== 2) fail('baseline is invalid')
const before = [[0, 0, 0, 1]]
const target = [[0.125, 0.375, 0.625, 0.875], [0.06666667, 0.13333334, 0.200000003, 0.266666681], [1, 0, 0.501960814, 0.250980407], [0, 0, 0, 0]]
for (const typeId of ['App::FeatureTest', 'App::FeatureTestException']) {
  const entry = report.cases.find(({ objectTypeId }) => objectTypeId === typeId)
  if (!entry || entry.propertyName !== 'ColourList' || entry.mutationDetected !== true || entry.restoredExactly !== true || !isDeepStrictEqual(entry.before.value, before) || !isDeepStrictEqual(entry.touchedAfterEdit.value, target) || !isDeepStrictEqual(entry.edited.value, target) || !isDeepStrictEqual(entry.touchedAfterRestore.value, before) || !isDeepStrictEqual(entry.restored.value, before)) fail(`${typeId} mutation values changed`)
  for (const snapshot of [entry.before, entry.touchedAfterEdit, entry.edited, entry.touchedAfterRestore, entry.restored]) if (snapshot.propertyTypeId !== 'App::PropertyColorList' || !isDeepStrictEqual(snapshot.propertyStatus, []) || !isDeepStrictEqual(snapshot.editorMode, []) || snapshot.shape?.applicable !== false || snapshot.objectSet?.length !== 1 || snapshot.objectSet[0].typeId !== typeId) fail(`${typeId} native metadata changed`)
  if (!isDeepStrictEqual(entry.before.objectSet, entry.edited.objectSet) || !isDeepStrictEqual(entry.before.objectSet, entry.restored.objectSet) || !isDeepStrictEqual(entry.before.shape, entry.edited.shape) || !isDeepStrictEqual(entry.before.shape, entry.restored.shape)) fail(`${typeId} object or Shape boundary drifted`)
  if (typeId === 'App::FeatureTest') {
    const states = [entry.before, entry.touchedAfterEdit, entry.edited, entry.touchedAfterRestore, entry.restored].map(({ objectState }) => objectState)
    if (!isDeepStrictEqual(states, [['Up-to-date'], ['Touched'], ['Up-to-date'], ['Touched'], ['Up-to-date']]) || entry.editRecomputeResult !== true || entry.restoreRecomputeResult !== true || entry.edited.statusString !== 'Valid' || entry.restored.statusString !== 'Valid') fail('normal host state sequence changed')
  } else {
    if (entry.hostExecution !== 'intrinsic-test-exception' || !entry.edited.objectState.includes('Invalid') || !entry.restored.objectState.includes('Invalid') || !entry.edited.statusString.includes('Testexception') || !entry.restored.statusString.includes('Testexception')) fail('FeatureTestException intrinsic diagnostic changed')
  }
}
console.log(JSON.stringify({ status: 'freecad-property-colorlist-mutation-pass', cases: report.caseCount, target, mutated: report.cases.filter(({ mutationDetected }) => mutationDetected).length, restoredExactly: report.cases.filter(({ restoredExactly }) => restoredExactly).length, normalStateSequence: ['Valid', 'Touched', 'Valid', 'Touched', 'Valid'], intrinsicHostDiagnostic: 'App::FeatureTestException' }, null, 2))
