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-area-success.json'), 'utf8'))
const fail = (message) => { throw new Error(`FreeCAD PropertyArea success check failed: ${message}`) }
const near = (left, right, tolerance = 2e-6) => Math.abs(left - right) <= tolerance
if (report.schemaVersion !== 1 || report.status !== 'pass' || report.baselineId !== 'freecad-1.1.1-property-area-success' || report.freecadVersion !== '1.1.1' || report.gitCommit !== '0108fd4b4850cc46e625b60e53cea7a7bbe69f8d') fail('baseline is invalid')
if (report.object?.typeId !== 'Measure::MeasureArea' || report.property?.name !== 'Area' || report.property.typeId !== 'App::PropertyArea' || report.property.group !== 'Measurement' || report.input?.name !== 'Elements' || report.input.typeId !== 'App::PropertyLinkSubList' || report.input.group !== 'Measurement') fail('native object/property identity changed')
if (report.diagnostics?.exception !== null || report.diagnostics.documentObjectCount !== 4 || report.sources?.length !== 3 || report.cases?.length !== 6) fail('native success cases are incomplete')
const expectedIds = ['empty-default', 'planar-face', 'cylindrical-face', 'surface-face', 'solid-volume', 'multi-element-sum']
const byId = new Map(report.cases.map((entry) => [entry.id, entry]))
for (const id of expectedIds) if (!byId.has(id)) fail(`missing case ${id}`)
for (const entry of report.cases) {
  if (entry.areaTypeId !== 'App::PropertyArea' || entry.elementsTypeId !== 'App::PropertyLinkSubList' || JSON.stringify(entry.propertyStatus) !== JSON.stringify(['24', '27']) || JSON.stringify(entry.editorMode) !== JSON.stringify(['ReadOnly']) || entry.shape?.applicable !== false || entry.object?.typeId !== 'Measure::MeasureArea' || JSON.stringify(entry.object.state) !== JSON.stringify(['Up-to-date']) || entry.object.status !== 'Valid') fail(`${entry.id} native metadata is invalid`)
  if (typeof entry.value?.numeric !== 'number' || !Number.isFinite(entry.value.numeric) || !String(entry.value.unit).includes('mm^2') || !near(entry.value.numeric, entry.expectedArea)) fail(`${entry.id} area did not match source Shape evidence`)
  for (const element of entry.elements ?? []) if (element.shapeNull !== false || element.shapeValid !== true || !(element.area > 0) || !['Face', 'Solid'].includes(element.shapeType)) fail(`${entry.id} contains invalid source geometry evidence`)
}
if (byId.get('empty-default').value.numeric !== 0 || byId.get('empty-default').elements.length !== 0) fail('empty default boundary changed')
if (byId.get('planar-face').elements[0]?.shapeType !== 'Face' || !near(byId.get('planar-face').value.numeric, 10)) fail('planar face evidence changed')
if (byId.get('cylindrical-face').elements[0]?.shapeType !== 'Face' || !(byId.get('cylindrical-face').value.numeric > 0)) fail('cylindrical face evidence changed')
if (byId.get('surface-face').elements[0]?.shapeType !== 'Face' || !(byId.get('surface-face').value.numeric > 0)) fail('surface face evidence changed')
if (byId.get('solid-volume').elements[0]?.shapeType !== 'Solid' || !near(byId.get('solid-volume').value.numeric, 160)) fail('solid volume surface-area evidence changed')
if (byId.get('multi-element-sum').elements.length !== 3 || !near(byId.get('multi-element-sum').value.numeric, byId.get('multi-element-sum').elements.reduce((total, element) => total + element.area, 0))) fail('multi-element sum evidence changed')
console.log(JSON.stringify({ status: 'freecad-property-area-success-pass', cases: expectedIds, values: Object.fromEntries(expectedIds.map((id) => [id, byId.get(id).value.numeric])), propertyStatus: byId.get('planar-face').propertyStatus, shapeApplicable: false }, null, 2))
