import { BitbybitGeometryRuntime } from './facade/geometryRuntime'
import { inspectFcstdArchive, instantiateFcstdShapeResource, serializeFcstdMetadataArchive } from './facade/fcstd'
import { createFacadeGeometryRecomputeExecutor, RecomputeCoordinator } from './facade/recomputeEngine'
import type { DocumentSnapshot, ShapeHandle, ShapeMassProperties, ShapeQualityReport } from './facade/types'

type Point3 = [number, number, number]
type GoldenPlacement = { translation?: Point3; rotation?: { axis: Point3; angle: number } }
type GoldenOperation = {
  type: 'box' | 'cylinder' | 'sphere' | 'cone' | 'torus' | 'prism' | 'wedge' | 'ellipsoid' | 'cut' | 'fuse' | 'common'
  length?: number
  width?: number
  height?: number
  radius?: number
  radius1?: number
  radius2?: number
  angle?: number
  placement?: GoldenPlacement
  base?: GoldenOperation
  tool?: GoldenOperation
}
type GoldenExpected = {
  shapeType: 'Solid' | 'Compound'
  isNull: false
  isValid: true
  solids: number
  faces?: number
  edges?: number
  vertices?: number
  volume: number
  area?: number
  boundingBox: { min: Point3; max: Point3 }
}
type GoldenScenario = {
  schemaVersion: 1
  id: string
  operation: GoldenOperation
  tolerance: { linear: number; scalar: number }
  expected: GoldenExpected
}
type Difference = { classification: 'unknown'; domain: 'identity' | 'shape' | 'topology' | 'resources'; path: string; expected: unknown; actual: unknown; tolerance?: number }
type KnownDifference = { classification: 'kernel-container-normalization'; domain: 'identity'; path: string; expected: unknown; actual: unknown }
type Comparison = { status: 'pass' | 'fail-unknown-difference'; differences: Difference[]; knownDifferences: KnownDifference[] }
type FormatRoundTrip = { sourceBytes: number; importedBytes: number; declaredUnit: 'millimeter' | 'unknown'; sourceVolume: number; importedVolume: number; sourceSolids: number; importedSolids: number; importedShapeType: string; importedStructuralValid: boolean; importedStructuralErrors: number; structuralNormalization: 'none' | 'format-topology-normalization'; status: 'pass' | 'fail' }
type GoldenExchangeFormat = 'step' | 'iges' | 'brep'
type FormatSummary = Record<GoldenExchangeFormat, { passed: number; totalBytes: number; maximumVolumeDelta: number; topologyNormalizations: number; importedShapeTypes: Record<string, number> }>
type ScenarioReport = {
  id: string
  operation: GoldenOperation['type']
  status: 'pass' | 'fail-unknown-difference'
  tolerance: GoldenScenario['tolerance']
  source: { quality: ShapeQualityReport; massProperties: ShapeMassProperties }
  fcstd: { archiveBytes: number; brepBytes: number; brepHash: string; shapeResources: number; references: number }
  imported: { quality: ShapeQualityReport; massProperties: ShapeMassProperties }
  formatRoundTrips: Record<GoldenExchangeFormat, FormatRoundTrip>
  comparisons: { sourceVsFreecad: Comparison; importedVsFreecad: Comparison; importedVsSource: Comparison }
}
type ProductRecomputeProbe = {
  status: 'pass'
  placedBox: { quality: ShapeQualityReport; massProperties: ShapeMassProperties; comparison: Comparison }
  cut: { quality: ShapeQualityReport; massProperties: ShapeMassProperties; comparison: Comparison }
  sphereTrim: { quality: ShapeQualityReport; massProperties: ShapeMassProperties; comparison: Comparison }
  torus: { quality: ShapeQualityReport; massProperties: ShapeMassProperties; comparison: Comparison }
  prism: { quality: ShapeQualityReport; massProperties: ShapeMassProperties; comparison: Comparison }
  wedge: { quality: ShapeQualityReport; massProperties: ShapeMassProperties; comparison: Comparison }
  ellipsoid: { quality: ShapeQualityReport; massProperties: ShapeMassProperties; comparison: Comparison }
  afterRelease: { shapeCount: number; kernelReferenceCount: number }
}
type HarnessReport = {
  schemaVersion: 1
  baselineId: 'freecad-1.1.1'
  freecadCommit: string
  bitbybitVersion: '1.1.1'
  browserId: 'chrome'
  geometryProvider: 'Bitbybit OCCT'
  unknownDifferencesFail: true
  scenarioCount: number
  reports: ScenarioReport[]
  productRecompute?: ProductRecomputeProbe
  summary: { passed: number; failed: number; knownDifferences: number; unknownDifferences: number; operationCounts: Record<string, number>; totalArchiveBytes: number; totalBrepBytes: number; formatRoundTrips: FormatSummary }
  beforeRelease: { shapeCount: number; kernelReferenceCount: number }
  afterRelease: { shapeCount: number; kernelReferenceCount: number }
  status: 'pass' | 'failed'
  error?: string
}

declare global {
  interface Window { __bitbybitFcstdGoldenReport?: HarnessReport }
}

const setStatus = (message: string) => { document.querySelector('#status')!.textContent = message }
const finite = (value: unknown): value is number => typeof value === 'number' && Number.isFinite(value)
const fnv1a = (bytes: Uint8Array) => {
  let hash = 0x811c9dc5
  for (const byte of bytes) { hash ^= byte; hash = Math.imul(hash, 0x01000193) >>> 0 }
  return hash.toString(16).padStart(8, '0')
}

const fcstdShapeDocument = (scenarioId: string, resourcePath: string): DocumentSnapshot => ({
  id: `fcstd-golden-${scenarioId}`,
  label: `FCStd golden ${scenarioId}`,
  version: 1,
  dirty: false,
  readOnly: false,
  units: 'mm',
  tree: [{ id: 'Model001', label: scenarioId, type: 'feature', state: 'valid' }],
  objects: [{ id: 'Model001', typeId: 'Part::Feature', properties: [{ name: 'Shape', label: 'Shape', group: 'Base', scope: 'data', type: 'Part::PropertyPartShape', value: { path: resourcePath, format: 'brep', elementMap: '1' } }] }],
  dependencies: [],
  recompute: { generation: 0, status: 'idle', objectStates: { Model001: 'up-to-date' }, dirtyObjects: [], order: [], errors: [] },
})

const compareExpected = (scenario: GoldenScenario, quality: ShapeQualityReport, mass: ShapeMassProperties): Comparison => {
  const differences: Difference[] = []
  const knownDifferences: KnownDifference[] = []
  const scalar = (domain: Difference['domain'], path: string, actual: number, expected: number, tolerance: number) => {
    const roundingAllowance = Number.EPSILON * Math.max(1, Math.abs(expected), Math.abs(actual)) * 32
    if (!finite(actual) || Math.abs(actual - expected) > tolerance + roundingAllowance) differences.push({ classification: 'unknown', domain, path, expected, actual, tolerance })
  }
  if (quality.isNull !== scenario.expected.isNull) differences.push({ classification: 'unknown', domain: 'shape', path: 'isNull', expected: scenario.expected.isNull, actual: quality.isNull })
  if (quality.structuralValid !== scenario.expected.isValid || quality.structuralErrors !== 0) differences.push({ classification: 'unknown', domain: 'shape', path: 'structuralValid', expected: true, actual: { valid: quality.structuralValid, errors: quality.structuralErrors } })
  if (quality.solids !== scenario.expected.solids) differences.push({ classification: 'unknown', domain: 'topology', path: 'solids', expected: scenario.expected.solids, actual: quality.solids })
  for (const key of ['faces', 'edges', 'vertices'] as const) {
    const expected = scenario.expected[key]
    if (expected !== undefined && quality[key] !== expected) differences.push({ classification: 'unknown', domain: 'topology', path: key, expected, actual: quality[key] })
  }
  const expectedShapeType = scenario.expected.shapeType.toLowerCase()
  if (quality.shapeType !== expectedShapeType) {
    if (((expectedShapeType === 'compound' && quality.shapeType === 'solid') || (expectedShapeType === 'solid' && quality.shapeType === 'compound')) && quality.solids === 1) knownDifferences.push({ classification: 'kernel-container-normalization', domain: 'identity', path: 'shapeType', expected: expectedShapeType, actual: quality.shapeType })
    else differences.push({ classification: 'unknown', domain: 'identity', path: 'shapeType', expected: expectedShapeType, actual: quality.shapeType })
  }
  scalar('shape', 'volume', mass.volume, scenario.expected.volume, scenario.tolerance.scalar)
  if (scenario.expected.area !== undefined) scalar('shape', 'area', mass.surfaceArea, scenario.expected.area, scenario.tolerance.scalar)
  for (const bound of ['min', 'max'] as const) for (let index = 0; index < 3; index += 1) scalar('shape', `boundingBox.${bound}[${index}]`, quality.boundingBox[bound][index], scenario.expected.boundingBox[bound][index], scenario.tolerance.linear)
  return { status: differences.length === 0 ? 'pass' : 'fail-unknown-difference', differences, knownDifferences }
}

const compareRoundTrip = (scenario: GoldenScenario, sourceQuality: ShapeQualityReport, sourceMass: ShapeMassProperties, importedQuality: ShapeQualityReport, importedMass: ShapeMassProperties): Comparison => {
  const differences: Difference[] = []
  const exact = (domain: Difference['domain'], path: string, expected: unknown, actual: unknown) => { if (actual !== expected) differences.push({ classification: 'unknown', domain, path, expected, actual }) }
  exact('identity', 'shapeType', sourceQuality.shapeType, importedQuality.shapeType)
  exact('shape', 'isNull', sourceQuality.isNull, importedQuality.isNull)
  exact('shape', 'structuralValid', sourceQuality.structuralValid, importedQuality.structuralValid)
  for (const key of ['structuralErrors', 'structuralWarnings', 'solids', 'faces', 'edges', 'vertices'] as const) exact(key.startsWith('structural') ? 'shape' : 'topology', key, sourceQuality[key], importedQuality[key])
  const scalar = (path: string, expected: number, actual: number, tolerance: number) => {
    const roundingAllowance = Number.EPSILON * Math.max(1, Math.abs(expected), Math.abs(actual)) * 32
    if (!finite(actual) || Math.abs(actual - expected) > tolerance + roundingAllowance) differences.push({ classification: 'unknown', domain: 'shape', path, expected, actual, tolerance })
  }
  scalar('volume', sourceMass.volume, importedMass.volume, scenario.tolerance.scalar)
  scalar('area', sourceMass.surfaceArea, importedMass.surfaceArea, scenario.tolerance.scalar)
  sourceMass.centerOfMass.forEach((value, index) => scalar(`centerOfMass[${index}]`, value, importedMass.centerOfMass[index], scenario.tolerance.linear))
  for (const bound of ['min', 'max'] as const) for (let index = 0; index < 3; index += 1) scalar(`boundingBox.${bound}[${index}]`, sourceQuality.boundingBox[bound][index], importedQuality.boundingBox[bound][index], scenario.tolerance.linear)
  return { status: differences.length === 0 ? 'pass' : 'fail-unknown-difference', differences, knownDifferences: [] }
}

const compareFormatRoundTrip = (sourceQuality: ShapeQualityReport, sourceMass: ShapeMassProperties, importedQuality: ShapeQualityReport, importedMass: ShapeMassProperties, sourceBytes: number, importedBytes: number, declaredUnit: 'millimeter' | 'unknown', tolerance: number, unitless = false): FormatRoundTrip => ({
  sourceBytes,
  importedBytes,
  declaredUnit,
  sourceVolume: sourceMass.volume,
  importedVolume: importedMass.volume,
  sourceSolids: sourceQuality.solids,
  importedSolids: importedQuality.solids,
  importedShapeType: importedQuality.shapeType,
  importedStructuralValid: importedQuality.structuralValid,
  importedStructuralErrors: importedQuality.structuralErrors,
  structuralNormalization: importedQuality.structuralErrors > 0 ? 'format-topology-normalization' : 'none',
  status: (unitless || declaredUnit === 'millimeter') && !importedQuality.isNull && ['solid', 'compound', 'shell', 'face'].includes(importedQuality.shapeType) && Math.abs(importedMass.volume - sourceMass.volume) <= tolerance ? 'pass' : 'fail',
})

const run = async (): Promise<HarnessReport> => {
  const runtime = new BitbybitGeometryRuntime()
  const reports: ScenarioReport[] = []
  let productRecompute: ProductRecomputeProbe | undefined
  let owned: ShapeHandle[] = []
  let phase = 'initialize'
  try {
    const capabilities = await runtime.initialize()
    if (capabilities.status !== 'ready') throw new Error(capabilities.reason || `Bitbybit runtime status is ${capabilities.status}.`)
    const manifestUrl = '/fixtures/freecad-golden/manifest.json'
    const manifest = await fetch(manifestUrl).then((response) => response.ok ? response.json() : Promise.reject(new Error(`Golden manifest fetch failed: ${response.status}`))) as { schemaVersion: number; baselineId: string; scenarios: Array<{ id: string; file: string }> }
    if (manifest.schemaVersion !== 1 || manifest.baselineId !== 'freecad-1.1.1' || manifest.scenarios.length !== 100) throw new Error('Chrome FCStd golden harness requires the locked 100-scenario manifest.')
    const loadScenario = async (id: string) => {
      const entry = manifest.scenarios.find((candidate) => candidate.id === id)
      if (!entry) throw new Error(`Product recompute probe scenario is missing: ${id}`)
      return fetch(new URL(entry.file, new URL(manifestUrl, location.origin))).then((response) => response.ok ? response.json() : Promise.reject(new Error(`Golden scenario fetch failed: ${id}`))) as Promise<GoldenScenario>
    }
    const [placedBoxScenario, cutScenario] = await Promise.all([loadScenario('part-box-009'), loadScenario('part-cut-through-hole')])
    const sphereTrimZ = 5 * Math.sin(Math.PI / 4)
    const sphereTrimScenario: GoldenScenario = {
      schemaVersion: 1,
      id: 'part-sphere-trim',
      operation: { type: 'sphere', radius: 5 },
      tolerance: { linear: 1e-6, scalar: 1e-6 },
      expected: {
        shapeType: 'Solid', isNull: false, isValid: true, solids: 1,
        volume: (Math.PI * (25 * (sphereTrimZ * 2) - (sphereTrimZ ** 3 - (-sphereTrimZ) ** 3) / 3)) / 3,
        boundingBox: { min: [-2.5, 0, -sphereTrimZ], max: [5, 5, sphereTrimZ] },
      },
    }
    const torusScenario: GoldenScenario = {
      schemaVersion: 1,
      id: 'part-torus',
      operation: { type: 'torus' },
      tolerance: { linear: 1e-6, scalar: 1e-6 },
      expected: { shapeType: 'Solid', isNull: false, isValid: true, solids: 1, volume: 60 * Math.PI ** 2, boundingBox: { min: [-12.988706403508727, -12.988706403508727, -2], max: [12.988706403508727, 12.988706403508727, 2] } },
    }
    const prismScenario: GoldenScenario = {
      schemaVersion: 1,
      id: 'part-prism',
      operation: { type: 'prism' },
      tolerance: { linear: 1e-6, scalar: 1e-6 },
      expected: { shapeType: 'Solid', isNull: false, isValid: true, solids: 1, faces: 8, edges: 18, vertices: 12, volume: 60 * Math.sqrt(3), boundingBox: { min: [-2, -2.6069374428281185, 0], max: [3.76326980708465, 1.7320508075688776, 10] } },
    }
    const wedgeScenario: GoldenScenario = {
      schemaVersion: 1,
      id: 'part-wedge',
      operation: { type: 'wedge' },
      tolerance: { linear: 1e-6, scalar: 1e-6 },
      expected: { shapeType: 'Solid', isNull: false, isValid: true, solids: 1, faces: 6, edges: 12, vertices: 8, volume: 2440 / 3, boundingBox: { min: [0, 0, 0], max: [10, 10, 10] } },
    }
    const ellipsoidScenario: GoldenScenario = {
      schemaVersion: 1,
      id: 'part-ellipsoid',
      operation: { type: 'ellipsoid' },
      tolerance: { linear: 1e-6, scalar: 1e-6 },
      expected: { shapeType: 'Solid', isNull: false, isValid: true, solids: 1, faces: 1, edges: 3, vertices: 2, volume: 133.9826640573845, boundingBox: { min: [-8, -6.92820323027551, -2], max: [4, 6.928203230275507, 2] } },
    }
    const productShapes = new Map<string, ShapeHandle>()
    const lengthProperty = (name: string, value: number) => ({ name, label: name, group: 'Parameters', scope: 'data' as const, type: 'App::PropertyLength' as const, value })
    const integerProperty = (name: string, value: number) => ({ name, label: name, group: 'Parameters', scope: 'data' as const, type: 'App::PropertyInteger' as const, value })
    const angleProperty = (name: string, value: number) => ({ name, label: name, group: 'Parameters', scope: 'data' as const, type: 'App::PropertyAngle' as const, value })
    const placementProperty = (translation: Point3) => ({ name: 'Placement', label: 'Placement', group: 'Attachment', scope: 'data' as const, type: 'App::PropertyPlacement' as const, value: { position: { x: translation[0], y: translation[1], z: translation[2] }, rotation: { axis: { x: 0, y: 0, z: 1 }, angle: 0 } } })
    const productDocument: DocumentSnapshot = {
      id: 'chrome-product-recompute', label: 'Chrome product recompute probe', version: 1, dirty: true, readOnly: false, units: 'mm',
      tree: [
        { id: 'PlacedBox', label: 'PlacedBox', type: 'feature', state: 'dirty' },
        { id: 'Base', label: 'Base', type: 'feature', state: 'dirty' },
        { id: 'Tool', label: 'Tool', type: 'feature', state: 'dirty' },
        { id: 'SphereTrim', label: 'SphereTrim', type: 'feature', state: 'dirty' },
        { id: 'Torus', label: 'Torus', type: 'feature', state: 'dirty' },
        { id: 'Prism', label: 'Prism', type: 'feature', state: 'dirty' },
        { id: 'Wedge', label: 'Wedge', type: 'feature', state: 'dirty' },
        { id: 'Ellipsoid', label: 'Ellipsoid', type: 'feature', state: 'dirty' },
        { id: 'Cut', label: 'Cut', type: 'feature', state: 'dirty' },
      ],
      objects: [
        { id: 'PlacedBox', typeId: 'Part::Box', properties: [lengthProperty('Length', 2), lengthProperty('Width', 10), lengthProperty('Height', 5), placementProperty([4, 4, 0])] },
        { id: 'Base', typeId: 'Part::Box', properties: [lengthProperty('Length', 20), lengthProperty('Width', 20), lengthProperty('Height', 20)] },
        { id: 'Tool', typeId: 'Part::Cylinder', properties: [lengthProperty('Radius', 5), lengthProperty('Height', 20), { name: 'Angle', label: 'Angle', group: 'Parameters', scope: 'data', type: 'App::PropertyAngle', value: 360 }, placementProperty([10, 10, 0])] },
        { id: 'SphereTrim', typeId: 'Part::Sphere', properties: [lengthProperty('Radius', 5), { name: 'Angle1', label: 'Lower angle', group: 'Sphere', scope: 'data', type: 'App::PropertyAngle', value: -45 }, { name: 'Angle2', label: 'Upper angle', group: 'Sphere', scope: 'data', type: 'App::PropertyAngle', value: 45 }, { name: 'Angle3', label: 'Azimuth angle', group: 'Sphere', scope: 'data', type: 'App::PropertyAngle', value: 120 }] },
        { id: 'Torus', typeId: 'Part::Torus', properties: [lengthProperty('Radius1', 10), lengthProperty('Radius2', 2), { name: 'Angle1', label: 'Lower angle', group: 'Torus', scope: 'data', type: 'App::PropertyAngle', value: -180 }, { name: 'Angle2', label: 'Upper angle', group: 'Torus', scope: 'data', type: 'App::PropertyAngle', value: 180 }, { name: 'Angle3', label: 'Azimuth angle', group: 'Torus', scope: 'data', type: 'App::PropertyAngle', value: 270 }] },
        { id: 'Prism', typeId: 'Part::Prism', properties: [integerProperty('Polygon', 6), lengthProperty('Circumradius', 2), lengthProperty('Height', 10), angleProperty('FirstAngle', 10), angleProperty('SecondAngle', -5)] },
        { id: 'Wedge', typeId: 'Part::Wedge', properties: [lengthProperty('Xmin', 0), lengthProperty('Ymin', 0), lengthProperty('Zmin', 0), lengthProperty('Z2min', 0), lengthProperty('X2min', 0), lengthProperty('Xmax', 10), lengthProperty('Ymax', 10), lengthProperty('Zmax', 10), lengthProperty('Z2max', 8), lengthProperty('X2max', 8)] },
        { id: 'Ellipsoid', typeId: 'Part::Ellipsoid', properties: [lengthProperty('Radius1', 2), lengthProperty('Radius2', 4), lengthProperty('Radius3', 0), angleProperty('Angle1', -90), angleProperty('Angle2', 90), angleProperty('Angle3', 360)] },
        { id: 'Cut', typeId: 'Part::Cut', properties: [
          { name: 'Base', label: 'Base', group: 'Boolean', scope: 'data', type: 'App::PropertyLink', value: 'Base' },
          { name: 'Tool', label: 'Tool', group: 'Boolean', scope: 'data', type: 'App::PropertyLink', value: 'Tool' },
          { name: 'Refine', label: 'Refine shape', group: 'Boolean', scope: 'data', type: 'App::PropertyBool', value: false },
        ] },
      ],
      dependencies: [{ sourceId: 'Cut', targetId: 'Base', relation: 'link' }, { sourceId: 'Cut', targetId: 'Tool', relation: 'link' }],
      recompute: { generation: 0, status: 'idle', objectStates: { PlacedBox: 'touched', Base: 'touched', Tool: 'touched', SphereTrim: 'touched', Torus: 'touched', Prism: 'touched', Wedge: 'touched', Ellipsoid: 'touched', Cut: 'touched' }, dirtyObjects: ['PlacedBox', 'Base', 'Tool', 'SphereTrim', 'Torus', 'Prism', 'Wedge', 'Ellipsoid', 'Cut'], order: [], errors: [] },
    }
    try {
      phase = 'product document recompute'
      const recompute = await new RecomputeCoordinator(createFacadeGeometryRecomputeExecutor(runtime, productShapes), () => productDocument.version).run(productDocument)
      if (recompute.status !== 'completed') throw new Error(`Product recompute probe failed: ${JSON.stringify(recompute.errors)}`)
      const placedBox = productShapes.get('PlacedBox')
      const cut = productShapes.get('Cut')
      const sphereTrim = productShapes.get('SphereTrim')
      const torus = productShapes.get('Torus')
      const prism = productShapes.get('Prism')
      const wedge = productShapes.get('Wedge')
      const ellipsoid = productShapes.get('Ellipsoid')
      if (!placedBox || !cut || !sphereTrim || !torus || !prism || !wedge || !ellipsoid) throw new Error('Product recompute probe did not commit the expected Shape handles.')
      phase = 'product recompute non-Torus quality'
      const [placedBoxQuality, placedBoxMass, cutQuality, cutMass, sphereTrimQuality, sphereTrimMass, prismQuality, prismMass, wedgeQuality, wedgeMass, ellipsoidQuality, ellipsoidMass] = await Promise.all([runtime.qualityReport(placedBox), runtime.massProperties(placedBox), runtime.qualityReport(cut), runtime.massProperties(cut), runtime.qualityReport(sphereTrim), runtime.massProperties(sphereTrim), runtime.qualityReport(prism), runtime.massProperties(prism), runtime.qualityReport(wedge), runtime.massProperties(wedge), runtime.qualityReport(ellipsoid), runtime.massProperties(ellipsoid)])
      phase = 'product Part::Torus quality report'
      const torusQuality = await runtime.qualityReport(torus)
      phase = 'product Part::Torus mass properties'
      const torusMass = await runtime.massProperties(torus)
      phase = 'product Part::Prism quality and mass properties'
      const prismComparison = compareExpected(prismScenario, prismQuality, prismMass)
      const wedgeComparison = compareExpected(wedgeScenario, wedgeQuality, wedgeMass)
      const placedBoxComparison = compareExpected(placedBoxScenario, placedBoxQuality, placedBoxMass)
      const cutComparison = compareExpected(cutScenario, cutQuality, cutMass)
      const sphereTrimComparison = compareExpected(sphereTrimScenario, sphereTrimQuality, sphereTrimMass)
      const torusComparison = compareExpected(torusScenario, torusQuality, torusMass)
      const ellipsoidComparison = compareExpected(ellipsoidScenario, ellipsoidQuality, ellipsoidMass)
      if (placedBoxComparison.status !== 'pass' || cutComparison.status !== 'pass' || sphereTrimComparison.status !== 'pass' || torusComparison.status !== 'pass' || prismComparison.status !== 'pass' || wedgeComparison.status !== 'pass' || ellipsoidComparison.status !== 'pass') throw new Error(`Product recompute differs from FreeCAD: ${JSON.stringify({ placedBoxComparison, cutComparison, sphereTrimComparison, torusComparison, prismComparison, wedgeComparison, ellipsoidComparison })}`)
      productRecompute = { status: 'pass', placedBox: { quality: placedBoxQuality, massProperties: placedBoxMass, comparison: placedBoxComparison }, cut: { quality: cutQuality, massProperties: cutMass, comparison: cutComparison }, sphereTrim: { quality: sphereTrimQuality, massProperties: sphereTrimMass, comparison: sphereTrimComparison }, torus: { quality: torusQuality, massProperties: torusMass, comparison: torusComparison }, prism: { quality: prismQuality, massProperties: prismMass, comparison: prismComparison }, wedge: { quality: wedgeQuality, massProperties: wedgeMass, comparison: wedgeComparison }, ellipsoid: { quality: ellipsoidQuality, massProperties: ellipsoidMass, comparison: ellipsoidComparison }, afterRelease: { shapeCount: -1, kernelReferenceCount: -1 } }
    } finally {
      for (const shape of [...new Set(productShapes.values())]) await runtime.release(shape)
      productShapes.clear()
      const remaining = runtime.capabilities()
      if (productRecompute) productRecompute.afterRelease = { shapeCount: remaining.shapeCount, kernelReferenceCount: remaining.kernelReferenceCount }
      if (remaining.shapeCount !== 0 || remaining.kernelReferenceCount !== 0) throw new Error(`Product recompute probe leaked Shape ownership: ${JSON.stringify(remaining)}`)
    }
    for (let scenarioIndex = 0; scenarioIndex < manifest.scenarios.length; scenarioIndex += 1) {
      const entry = manifest.scenarios[scenarioIndex]
      setStatus(`Running ${scenarioIndex + 1}/100: ${entry.id}`)
      const scenario = await fetch(new URL(entry.file, new URL(manifestUrl, location.origin))).then((response) => response.ok ? response.json() : Promise.reject(new Error(`Golden scenario fetch failed: ${entry.id}`))) as GoldenScenario
      if (scenario.schemaVersion !== 1 || scenario.id !== entry.id || !finite(scenario.tolerance.linear) || !finite(scenario.tolerance.scalar)) throw new Error(`Malformed golden scenario: ${entry.id}`)
      const documentContext = { documentId: `chrome-fcstd-${entry.id}`, documentVersion: 1 }
      const own = (shape: ShapeHandle) => { owned.push(shape); return shape }
      const place = async (shape: ShapeHandle, placement?: GoldenPlacement) => {
        if (!placement) return shape
        return own(await runtime.applyPlacement({
          ...documentContext,
          shape,
          placement: {
            translation: placement.translation ?? [0, 0, 0],
            rotationAxis: placement.rotation?.axis ?? [0, 0, 1],
            rotationAngle: placement.rotation?.angle ?? 0,
          },
        }))
      }
      const build = async (operation: GoldenOperation): Promise<ShapeHandle> => {
        let shape: ShapeHandle
        const translation = operation.placement?.translation ?? [0, 0, 0]
        const rotatePrimitive = async (primitive: ShapeHandle) => operation.placement?.rotation
          ? place(primitive, { rotation: operation.placement.rotation })
          : primitive
        if (operation.type === 'box') {
          if (!finite(operation.length) || !finite(operation.width) || !finite(operation.height)) throw new Error(`${entry.id} has invalid box inputs.`)
          shape = await rotatePrimitive(own(await runtime.createBox({ ...documentContext, width: operation.length, height: operation.width, length: operation.height, center: [translation[0] + operation.length / 2, translation[1] + operation.width / 2, translation[2] + operation.height / 2], originOnCenter: true })))
        } else if (operation.type === 'cylinder') {
          if (!finite(operation.radius) || !finite(operation.height)) throw new Error(`${entry.id} has invalid cylinder inputs.`)
          shape = await rotatePrimitive(own(await runtime.createCylinder({ ...documentContext, radius: operation.radius, height: operation.height, angle: operation.angle ?? 360, center: translation, direction: [0, 0, 1], originOnCenter: false })))
        } else if (operation.type === 'sphere') {
          if (!finite(operation.radius)) throw new Error(`${entry.id} has invalid sphere inputs.`)
          shape = await rotatePrimitive(own(await runtime.createSphere({ ...documentContext, radius: operation.radius, center: translation })))
        } else if (operation.type === 'cone') {
          if (!finite(operation.radius1) || !finite(operation.radius2) || !finite(operation.height)) throw new Error(`${entry.id} has invalid cone inputs.`)
          shape = await rotatePrimitive(own(await runtime.createCone({ ...documentContext, radius1: operation.radius1, radius2: operation.radius2, height: operation.height, angle: operation.angle ?? 360, center: translation, direction: [0, 0, 1] })))
        } else if (operation.type === 'ellipsoid') {
          shape = await rotatePrimitive(own(await runtime.createEllipsoid({ ...documentContext, radius1: 2, radius2: 4, radius3: 0, angle1: -90, angle2: 90, angle3: 360, center: translation })))
        } else if (operation.type === 'wedge') {
          shape = await rotatePrimitive(own(await runtime.createWedge({ ...documentContext, xmin: 0, ymin: 0, zmin: 0, z2min: 0, x2min: 0, xmax: 10, ymax: 10, zmax: 10, z2max: 8, x2max: 8, center: translation })))
        } else {
          if (!operation.base || !operation.tool) throw new Error(`${entry.id} has incomplete Boolean inputs.`)
          const base = await build(operation.base)
          const tool = await build(operation.tool)
          shape = own(operation.type === 'fuse'
            ? await runtime.union({ ...documentContext, shapes: [base, tool], keepEdges: true })
            : operation.type === 'cut'
              ? await runtime.cut({ ...documentContext, base, tools: [tool], keepEdges: true })
              : await runtime.intersection({ ...documentContext, shapes: [base, tool], keepEdges: true }))
          shape = await place(shape, operation.placement)
        }
        return shape
      }
      try {
        const source = await build(scenario.operation)
        const [sourceQuality, sourceMass, brep, step, iges] = await Promise.all([runtime.qualityReport(source), runtime.massProperties(source), runtime.exportBrep(source, 'Model001.Shape.brp'), runtime.exportStep(source, 'Model001.step'), runtime.exportIges(source, 'Model001.iges')])
        const [stepImported, igesImported, brepImported] = await Promise.all([
          runtime.importShape({ ...documentContext, format: 'step', text: step.text }),
          runtime.importShape({ ...documentContext, format: 'iges', text: iges.text }),
          runtime.importShape({ ...documentContext, format: 'brep', text: brep.text }),
        ])
        own(stepImported)
        own(igesImported)
        own(brepImported)
        const [[stepQuality, stepMass], [igesQuality, igesMass], [brepQuality, brepMass]] = await Promise.all([
          Promise.all([runtime.qualityReport(stepImported), runtime.massProperties(stepImported)]),
          Promise.all([runtime.qualityReport(igesImported), runtime.massProperties(igesImported)]),
          Promise.all([runtime.qualityReport(brepImported), runtime.massProperties(brepImported)]),
        ])
        const brepBytes = new TextEncoder().encode(brep.text)
        const formatRoundTrips = {
          step: compareFormatRoundTrip(sourceQuality, sourceMass, stepQuality, stepMass, new TextEncoder().encode(step.text).byteLength, new TextEncoder().encode(step.text).byteLength, /SI_UNIT\(\.MILLI\.,\.METRE\.\)/.test(step.text) ? 'millimeter' : 'unknown', scenario.tolerance.scalar),
          iges: compareFormatRoundTrip(sourceQuality, sourceMass, igesQuality, igesMass, new TextEncoder().encode(iges.text).byteLength, new TextEncoder().encode(iges.text).byteLength, /2HMM/.test(iges.text) ? 'millimeter' : 'unknown', scenario.tolerance.scalar),
          brep: compareFormatRoundTrip(sourceQuality, sourceMass, brepQuality, brepMass, brepBytes.byteLength, brepBytes.byteLength, 'unknown', scenario.tolerance.scalar, true),
        }
        if (Object.values(formatRoundTrips).some((roundTrip) => roundTrip.status !== 'pass')) throw new Error(`${entry.id} format round-trip failed: ${JSON.stringify(formatRoundTrips)}`)
        const resourcePath = 'Part/Model001.Shape.brp'
        const archive = serializeFcstdMetadataArchive(fcstdShapeDocument(entry.id, resourcePath), { opaqueEntries: { [resourcePath]: brepBytes } })
        const inspection = inspectFcstdArchive(archive)
        const shapeResource = inspection.shapeResources.find((resource) => resource.path === resourcePath)
        if (shapeResource?.status !== 'available' || shapeResource.byteLength !== brepBytes.byteLength) throw new Error(`${entry.id} FCStd Shape resource inspection failed.`)
        const imported = await instantiateFcstdShapeResource(archive, resourcePath, ({ format, text }) => runtime.importShape({ ...documentContext, format, text }), { release: (shape) => runtime.release(shape) })
        own(imported.shape)
        const [importedQuality, importedMass] = await Promise.all([runtime.qualityReport(imported.shape), runtime.massProperties(imported.shape)])
        const sourceVsFreecad = compareExpected(scenario, sourceQuality, sourceMass)
        const importedVsFreecad = compareExpected(scenario, importedQuality, importedMass)
        const importedVsSource = compareRoundTrip(scenario, sourceQuality, sourceMass, importedQuality, importedMass)
        const status = [sourceVsFreecad, importedVsFreecad, importedVsSource].every((comparison) => comparison.status === 'pass') ? 'pass' : 'fail-unknown-difference'
        reports.push({
          id: entry.id,
          operation: scenario.operation.type,
          status,
          tolerance: scenario.tolerance,
          source: { quality: sourceQuality, massProperties: sourceMass },
          fcstd: { archiveBytes: archive.byteLength, brepBytes: brepBytes.byteLength, brepHash: fnv1a(brepBytes), shapeResources: inspection.shapeResources.length, references: imported.references.length },
          imported: { quality: importedQuality, massProperties: importedMass },
          formatRoundTrips,
          comparisons: { sourceVsFreecad, importedVsFreecad, importedVsSource },
        })
        if (status !== 'pass') throw new Error(`${entry.id} produced unknown differences: ${JSON.stringify({ sourceVsFreecad, importedVsFreecad, importedVsSource })}`)
      } finally {
        for (const shape of owned.reverse()) await runtime.release(shape)
        owned = []
        const remaining = runtime.capabilities()
        if (remaining.shapeCount !== 0 || remaining.kernelReferenceCount !== 0) throw new Error(`${entry.id} leaked Shape ownership: ${JSON.stringify(remaining)}`)
      }
    }
    const beforeRelease = { shapeCount: 0, kernelReferenceCount: 0 }
    const afterRelease = { shapeCount: runtime.capabilities().shapeCount, kernelReferenceCount: runtime.capabilities().kernelReferenceCount }
    const knownDifferences = reports.reduce((sum, report) => sum + Object.values(report.comparisons).reduce((count, comparison) => count + comparison.knownDifferences.length, 0), 0)
    const unknownDifferences = reports.reduce((sum, report) => sum + Object.values(report.comparisons).reduce((count, comparison) => count + comparison.differences.length, 0), 0)
    const summarizeFormat = (format: GoldenExchangeFormat) => {
      const values = reports.map((report) => report.formatRoundTrips[format])
      return {
        passed: values.filter((value) => value.status === 'pass').length,
        totalBytes: values.reduce((sum, value) => sum + value.sourceBytes, 0),
        maximumVolumeDelta: Math.max(...values.map((value) => Math.abs(value.importedVolume - value.sourceVolume))),
        topologyNormalizations: values.filter((value) => value.structuralNormalization === 'format-topology-normalization').length,
        importedShapeTypes: Object.fromEntries([...new Set(values.map((value) => value.importedShapeType))].sort().map((shapeType) => [shapeType, values.filter((value) => value.importedShapeType === shapeType).length])),
      }
    }
    return {
      schemaVersion: 1,
      baselineId: 'freecad-1.1.1',
      freecadCommit: '0108fd4b4850cc46e625b60e53cea7a7bbe69f8d',
      bitbybitVersion: '1.1.1',
      browserId: 'chrome',
      geometryProvider: 'Bitbybit OCCT',
      unknownDifferencesFail: true,
      scenarioCount: reports.length,
      reports,
      productRecompute,
      summary: {
        passed: reports.filter((report) => report.status === 'pass').length,
        failed: reports.filter((report) => report.status !== 'pass').length,
        knownDifferences,
        unknownDifferences,
        operationCounts: Object.fromEntries([...new Set(reports.map((report) => report.operation))].sort().map((operation) => [operation, reports.filter((report) => report.operation === operation).length])),
        totalArchiveBytes: reports.reduce((sum, report) => sum + report.fcstd.archiveBytes, 0),
        totalBrepBytes: reports.reduce((sum, report) => sum + report.fcstd.brepBytes, 0),
        formatRoundTrips: { step: summarizeFormat('step'), iges: summarizeFormat('iges'), brep: summarizeFormat('brep') },
      },
      beforeRelease,
      afterRelease,
      status: unknownDifferences === 0 && reports.length === 100 && afterRelease.shapeCount === 0 && afterRelease.kernelReferenceCount === 0 ? 'pass' : 'failed',
    }
  } catch (error) {
    for (const shape of owned.reverse()) await runtime.release(shape).catch(() => {})
    const capabilities = runtime.capabilities()
    return {
      schemaVersion: 1,
      baselineId: 'freecad-1.1.1',
      freecadCommit: '0108fd4b4850cc46e625b60e53cea7a7bbe69f8d',
      bitbybitVersion: '1.1.1',
      browserId: 'chrome',
      geometryProvider: 'Bitbybit OCCT',
      unknownDifferencesFail: true,
      scenarioCount: reports.length,
      reports,
      productRecompute,
      summary: { passed: reports.filter((report) => report.status === 'pass').length, failed: reports.filter((report) => report.status !== 'pass').length, knownDifferences: 0, unknownDifferences: 1, operationCounts: {}, totalArchiveBytes: 0, totalBrepBytes: 0, formatRoundTrips: { step: { passed: 0, totalBytes: 0, maximumVolumeDelta: 0, topologyNormalizations: 0, importedShapeTypes: {} }, iges: { passed: 0, totalBytes: 0, maximumVolumeDelta: 0, topologyNormalizations: 0, importedShapeTypes: {} }, brep: { passed: 0, totalBytes: 0, maximumVolumeDelta: 0, topologyNormalizations: 0, importedShapeTypes: {} } } },
      beforeRelease: { shapeCount: capabilities.shapeCount, kernelReferenceCount: capabilities.kernelReferenceCount },
      afterRelease: { shapeCount: capabilities.shapeCount, kernelReferenceCount: capabilities.kernelReferenceCount },
      status: 'failed',
      error: `${phase}: ${error instanceof Error ? error.message : String(error)}`,
    }
  } finally {
    runtime.dispose()
  }
}

void run().then((report) => {
  window.__bitbybitFcstdGoldenReport = report
  setStatus(report.status === 'pass' ? `Passed ${report.scenarioCount} FCStd golden scenarios.` : report.error ?? 'FCStd golden harness failed.')
})
