import assert from 'node:assert/strict'
import { resolve } from 'node:path'
import createOcctHistory from './dist/bitbybit-occt-history.js'

const dist = resolve(import.meta.dirname, 'dist')
const occt = await createOcctHistory({ locateFile: (path) => resolve(dist, path) })
assert.match(occt.occtVersion(), /^8\./)
const object = occt.makeBox(10, 10, 10)
const tool = occt.makeBox(5, 5, 5)
const response = occt.booleanHistory(object, tool, 'cut')
const objectStep = occt.shapeToStep(object)
const toolStep = occt.shapeToStep(tool)
assert.match(objectStep, /^ISO-10303-21;/)
assert.match(toolStep, /^ISO-10303-21;/)
const serializedResponse = occt.booleanHistoryFromStep(objectStep, toolStep, 'cut')
assert.equal(response.provider, 'occt-native')
assert.equal(response.records.every((record) => ['generated', 'modified', 'deleted'].includes(record.relation)), true)
assert.equal(typeof response.hasModified, 'boolean')
assert.equal(typeof response.hasGenerated, 'boolean')
assert.equal(typeof response.hasDeleted, 'boolean')
assert.equal(serializedResponse.provider, 'occt-native')
assert.equal(serializedResponse.records.length > 0, true)
assert.match(serializedResponse.resultStep, /^ISO-10303-21;/)
const pocketBase = occt.makeBox(10, 10, 10)
const pocketProfile = occt.makeRectangleFace(2, 3)
const pocket = occt.pocketHistory(pocketBase, pocketProfile, 0, 0, 5)
const pocketFromStep = occt.pocketHistoryFromStep(occt.shapeToStep(pocketBase), occt.shapeToStep(pocketProfile), 0, 0, 5)
assert.equal(pocket.provider, 'occt-native')
assert.equal(pocket.summary.isValid, true)
assert.equal(pocket.summary.solids, 1)
assert.ok(Math.abs(pocket.summary.volume - 970) <= 1e-7)
assert.equal(pocket.records.length > 0, true)
assert.equal(pocketFromStep.summary.isValid, true)
assert.ok(Math.abs(pocketFromStep.summary.volume - 970) <= 1e-7)
const revolution = occt.revolutionHistory(pocketProfile, -1, 0, 0, 0, 1, 0, 360)
const revolutionFromStep = occt.revolutionHistoryFromStep(occt.shapeToStep(pocketProfile), -1, 0, 0, 0, 1, 0, 360)
assert.equal(revolution.provider, 'occt-native')
assert.equal(revolution.summary.isValid, true)
assert.equal(revolution.summary.solids, 1)
assert.equal(revolution.records.length > 0, true)
assert.equal(revolutionFromStep.summary.isValid, true)
assert.equal(revolutionFromStep.summary.solids, 1)
const grooveBase = occt.makeBoxPlaced(10, 10, 8, -5, 0, -4)
const grooveProfile = occt.makeRectangleFacePlaced(1, 3, 0.5, 2, 0)
const groove = occt.grooveHistory(grooveBase, grooveProfile, 0, 0, 0, 0, 1, 0, 360)
const grooveFromStep = occt.grooveHistoryFromStep(occt.shapeToStep(grooveBase), occt.shapeToStep(grooveProfile), 0, 0, 0, 0, 1, 0, 360)
assert.equal(groove.provider, 'occt-native')
assert.equal(groove.summary.isValid, true)
assert.equal(groove.summary.solids, 1)
assert.ok(Math.abs(groove.summary.volume - (800 - 6 * Math.PI)) <= 1e-7)
assert.equal(groove.records.length > 0, true)
assert.equal(grooveFromStep.summary.isValid, true)
assert.ok(Math.abs(grooveFromStep.summary.volume - groove.summary.volume) <= 1e-7)
const loftFirst = occt.makeRectangleFacePlaced(2, 2, 0, 0, 0)
const loftSecond = occt.makeRectangleFacePlaced(2, 2, 0, 0, 5)
const loftFromStep = occt.loftHistoryFromStep(occt.shapeToStep(loftFirst), occt.shapeToStep(loftSecond), false)
assert.equal(loftFromStep.provider, 'occt-native')
assert.equal(loftFromStep.summary.isValid, true)
assert.equal(loftFromStep.summary.solids, 1)
assert.ok(Math.abs(loftFromStep.summary.volume - 20) <= 1e-7)
assert.equal(loftFromStep.records.length > 0, true)
assert.equal(loftFromStep.records.some((record) => record.source === 'object'), true)
assert.equal(loftFromStep.records.some((record) => record.source === 'tool'), true)
const pipeProfile = occt.makeRectangleFace(2, 2)
const pipeSpine = occt.makeLineWire(0, 0, 0, 0, 0, 5)
const pipeFromStep = occt.pipeHistoryFromStep(occt.shapeToStep(pipeProfile), occt.shapeToStep(pipeSpine))
assert.equal(pipeFromStep.provider, 'occt-native')
assert.equal(pipeFromStep.summary.isValid, true)
assert.equal(pipeFromStep.summary.solids, 1)
assert.ok(Math.abs(pipeFromStep.summary.volume - 20) <= 1e-7)
assert.equal(pipeFromStep.records.length > 0, true)
assert.equal(pipeFromStep.records.some((record) => record.source === 'object'), true)
assert.equal(pipeFromStep.records.some((record) => record.source === 'tool'), true)
const filletBase = occt.makeBox(6, 6, 6)
const filletFromStep = occt.filletHistoryFromStep(occt.shapeToStep(filletBase), 0.4)
assert.equal(filletFromStep.provider, 'occt-native')
assert.equal(filletFromStep.summary.isValid, true)
assert.equal(filletFromStep.summary.solids, 1)
assert.equal(filletFromStep.records.length > 0, true)
assert.equal(filletFromStep.hasModified, true)
assert.equal(filletFromStep.hasGenerated, true)
assert.equal(filletFromStep.hasDeleted, true)
const chamferFromStep = occt.chamferHistoryFromStep(occt.shapeToStep(filletBase), 0.4)
assert.equal(chamferFromStep.provider, 'occt-native')
assert.equal(chamferFromStep.summary.isValid, true)
assert.equal(chamferFromStep.summary.solids, 1)
assert.equal(chamferFromStep.records.length > 0, true)
assert.equal(chamferFromStep.hasModified, true)
assert.equal(chamferFromStep.hasGenerated, true)
assert.equal(chamferFromStep.hasDeleted, true)
const draftBase = occt.makeBox(10, 10, 10)
const draftFromStep = occt.draftHistoryFromStep(occt.shapeToStep(draftBase), 0, 5, 0, 0, 1, 0, 0, 0, 0, 0, 1, false)
assert.equal(draftFromStep.provider, 'occt-native')
assert.equal(draftFromStep.summary.isValid, true)
assert.equal(draftFromStep.summary.solids, 1)
assert.equal(draftFromStep.records.length > 0, true)
assert.equal(draftFromStep.hasModified, true)
const thicknessBase = occt.makeBox(6, 6, 6)
const thicknessFromStep = occt.thicknessHistoryFromStep(occt.shapeToStep(thicknessBase), 1, -0.4, false)
assert.equal(thicknessFromStep.provider, 'occt-native')
assert.equal(thicknessFromStep.summary.isValid, true)
assert.equal(thicknessFromStep.summary.solids, 1)
assert.equal(thicknessFromStep.records.length > 0, true)
assert.equal(thicknessFromStep.hasModified, true)
const linearPatternFromStep = occt.linearPatternHistoryFromStep(occt.shapeToStep(occt.makeBox(2, 2, 2)), 2, 0, 0)
assert.equal(linearPatternFromStep.provider, 'occt-native')
assert.equal(linearPatternFromStep.summary.isValid, true)
assert.equal(linearPatternFromStep.summary.solids, 1)
assert.ok(Math.abs(linearPatternFromStep.summary.volume - 16) <= 1e-7)
assert.equal(linearPatternFromStep.records.length > 0, true)
const polarPatternBase = occt.makeBoxPlaced(2, 1, 1, -1, -0.5, -0.5)
const polarPatternFromStep = occt.polarPatternHistoryFromStep(occt.shapeToStep(polarPatternBase), 0, 0, 0, 0, 0, 1, 90)
assert.equal(polarPatternFromStep.provider, 'occt-native')
assert.equal(polarPatternFromStep.summary.isValid, true)
assert.equal(polarPatternFromStep.summary.solids, 1)
assert.ok(Math.abs(polarPatternFromStep.summary.volume - 3) <= 1e-7)
assert.equal(polarPatternFromStep.records.length > 0, true)
const mirroredBase = occt.makeBoxPlaced(2, 1, 1, -0.5, -0.5, -0.5)
const mirroredFromStep = occt.mirroredHistoryFromStep(occt.shapeToStep(mirroredBase), 0, 0, 0, 1, 0, 0)
assert.equal(mirroredFromStep.provider, 'occt-native')
assert.equal(mirroredFromStep.summary.isValid, true)
assert.equal(mirroredFromStep.summary.solids, 1)
assert.ok(Math.abs(mirroredFromStep.summary.volume - 3) <= 1e-7)
assert.equal(mirroredFromStep.records.length > 0, true)
const orderedMultiTransform = occt.multiTransformHistoryFromStep(occt.shapeToStep(mirroredBase), [
  { type: 'linear', direction: [1, 0, 0] },
  { type: 'mirrored', axisOrigin: [0, 0, 0], direction: [1, 0, 0] },
])
assert.equal(orderedMultiTransform.provider, 'occt-native')
assert.equal(orderedMultiTransform.summary.isValid, true)
assert.equal(orderedMultiTransform.summary.solids, 1)
assert.ok(Math.abs(orderedMultiTransform.summary.volume - 5) <= 1e-7)
assert.equal(orderedMultiTransform.records.length > 0, true)
const holeFromStep = occt.holeHistoryFromStep(occt.shapeToStep(occt.makeBox(10, 10, 10)), 1, 10, 0, 0, -5, 0, 0, 1)
assert.equal(holeFromStep.provider, 'occt-native')
assert.equal(holeFromStep.summary.isValid, true)
assert.equal(holeFromStep.summary.solids, 1)
assert.equal(holeFromStep.records.length > 0, true)
assert.equal(holeFromStep.hasModified, true)
assert.equal(holeFromStep.hasDeleted, true)
console.log(JSON.stringify({ occtVersion: response.occtVersion, recordCount: response.records.length, hasModified: response.hasModified, hasGenerated: response.hasGenerated, hasDeleted: response.hasDeleted, pocket: { recordCount: pocket.records.length, volume: pocket.summary.volume, fromStepVolume: pocketFromStep.summary.volume, hasModified: pocket.hasModified, hasGenerated: pocket.hasGenerated, hasDeleted: pocket.hasDeleted }, revolution: { recordCount: revolution.records.length, volume: revolution.summary.volume, fromStepVolume: revolutionFromStep.summary.volume, hasModified: revolution.hasModified, hasGenerated: revolution.hasGenerated, hasDeleted: revolution.hasDeleted }, groove: { recordCount: groove.records.length, volume: groove.summary.volume, fromStepVolume: grooveFromStep.summary.volume, hasModified: groove.hasModified, hasGenerated: groove.hasGenerated, hasDeleted: groove.hasDeleted }, loft: { recordCount: loftFromStep.records.length, volume: loftFromStep.summary.volume, hasGenerated: loftFromStep.hasGenerated }, pipe: { recordCount: pipeFromStep.records.length, volume: pipeFromStep.summary.volume, hasModified: pipeFromStep.hasModified, hasGenerated: pipeFromStep.hasGenerated }, fillet: { recordCount: filletFromStep.records.length, volume: filletFromStep.summary.volume, hasModified: filletFromStep.hasModified, hasGenerated: filletFromStep.hasGenerated, hasDeleted: filletFromStep.hasDeleted }, chamfer: { recordCount: chamferFromStep.records.length, volume: chamferFromStep.summary.volume, hasModified: chamferFromStep.hasModified, hasGenerated: chamferFromStep.hasGenerated, hasDeleted: chamferFromStep.hasDeleted }, draft: { recordCount: draftFromStep.records.length, volume: draftFromStep.summary.volume, hasModified: draftFromStep.hasModified, hasGenerated: draftFromStep.hasGenerated, hasDeleted: draftFromStep.hasDeleted }, thickness: { recordCount: thicknessFromStep.records.length, volume: thicknessFromStep.summary.volume, hasModified: thicknessFromStep.hasModified, hasGenerated: thicknessFromStep.hasGenerated, hasDeleted: thicknessFromStep.hasDeleted }, mirrored: { recordCount: mirroredFromStep.records.length, volume: mirroredFromStep.summary.volume, hasModified: mirroredFromStep.hasModified, hasGenerated: mirroredFromStep.hasGenerated, hasDeleted: mirroredFromStep.hasDeleted }, orderedMultiTransform: { recordCount: orderedMultiTransform.records.length, volume: orderedMultiTransform.summary.volume, hasModified: orderedMultiTransform.hasModified, hasGenerated: orderedMultiTransform.hasGenerated, hasDeleted: orderedMultiTransform.hasDeleted }, hole: { recordCount: holeFromStep.records.length, volume: holeFromStep.summary.volume, hasModified: holeFromStep.hasModified, hasGenerated: holeFromStep.hasGenerated, hasDeleted: holeFromStep.hasDeleted } }, null, 2))
