import test from 'node:test'
import assert from 'node:assert/strict'
import { ExternalPartDesignLinkRegistry, type ExternalSourceEvidence } from '../src/facade/externalPartDesignLinks'

const source = (revision = 1): ExternalSourceEvidence => ({
  documentId: 'XLinkSource',
  path: '/projects/XLinkSource.FCStd',
  revision,
  objects: {
    SourceBox: { objectId: 'SourceBox', length: revision === 1 ? 4 : 8, width: revision === 1 ? 5 : 9, height: 6, volume: revision === 1 ? 120 : 432, surfaceArea: revision === 1 ? 148 : 348, shapeId: `source-${revision}` },
    SecondBox: { objectId: 'SecondBox', length: 3, width: 7, height: revision === 1 ? 2 : 4, volume: revision === 1 ? 42 : 84, surfaceArea: revision === 1 ? 82 : 122, shapeId: `second-${revision}` },
  },
})

test('external PartDesign links close, cache, relink and preserve history', () => {
  const registry = new ExternalPartDesignLinkRegistry(source())
  assert.equal(registry.snapshot().properties.XLinkSubList.length, 2)
  registry.closeSource()
  assert.deepEqual(registry.snapshot().properties.XLinkList, [])
  assert.equal(registry.snapshot().binder.cacheState, 'cached')
  registry.markSourceMissing()
  const restored = ExternalPartDesignLinkRegistry.deserialize(registry.serialize())
  assert.equal(restored.snapshot().source.status, 'missing')
  restored.relinkSource(source())
  restored.editSource(source(2))
  assert.equal(restored.snapshot().binder.area, 54)
  restored.undo()
  assert.equal(restored.snapshot().binder.area, 30)
  restored.redo()
  assert.equal(restored.snapshot().binder.area, 54)
})

test('external PartDesign links reject divergent relink and unresolved edits', () => {
  const registry = new ExternalPartDesignLinkRegistry(source())
  registry.closeSource()
  assert.throws(() => registry.editSource(source(2)), /open and resolved/)
  assert.throws(() => registry.relinkSource({ ...source(), path: '/projects/Other.FCStd' }), /identity/)
  assert.throws(() => new ExternalPartDesignLinkRegistry({ ...source(), objects: { ...source().objects, SourceBox: { ...source().objects.SourceBox, volume: 1 } } }), /geometry evidence/)
})
