import { readFile, readdir } from 'node:fs/promises'
import { resolve } from 'node:path'

const root = resolve(new URL('..', import.meta.url).pathname)
const inventory = JSON.parse(await readFile(resolve(root, 'config/freecad-type-property-inventory.json'), 'utf8'))
const fail = (message) => { throw new Error(`FreeCAD TypeId/property inventory: ${message}`) }
if (inventory.schemaVersion !== 1) fail('unsupported schemaVersion.')
if (inventory.baseline?.freecadVersion !== '1.1.1' || inventory.baseline?.commit !== '0108fd4b4850cc46e625b60e53cea7a7bbe69f8d') fail('baseline mismatch.')
if (inventory.moduleCount !== 34 || !Array.isArray(inventory.modules) || inventory.modules.length !== 34) fail('expected exactly 34 modules.')
const names = new Set()
for (const module of inventory.modules) {
  if (!module.name || names.has(module.name)) fail(`duplicate or empty module '${module.name}'.`)
  names.add(module.name)
  if (!Array.isArray(module.objects)) fail(`${module.name}.objects must be an array.`)
  for (const object of module.objects) {
    if (typeof object.sourceFile !== 'string' || !object.sourceFile.startsWith('src/Mod/')) fail(`${module.name} has an invalid sourceFile.`)
    for (const field of ['classes', 'typeIdSymbols', 'propertyRegistrations', 'propertyMembers', 'pythonProperties']) if (!Array.isArray(object[field])) fail(`${module.name}/${object.sourceFile}.${field} must be an array.`)
    for (const value of [...object.classes, ...object.typeIdSymbols, ...object.propertyRegistrations]) if (typeof value !== 'string' || !value) fail(`${module.name}/${object.sourceFile} contains an invalid symbol.`)
    for (const value of [...object.propertyMembers, ...object.pythonProperties]) if (!value || typeof value.name !== 'string' || !value.name) fail(`${module.name}/${object.sourceFile} contains an invalid property.`)
  }
}
const sourceRoot = process.env.FREECAD_SOURCE_DIR ? resolve(process.env.FREECAD_SOURCE_DIR) : resolve(root, inventory.baseline.sourcePath || '.cache/freecad/FreeCAD')
let sourceAvailable = false
try {
  const entries = await readdir(resolve(sourceRoot, 'src/Mod'), { withFileTypes: true })
  const sourceNames = new Set(entries.filter((entry) => entry.isDirectory()).map((entry) => entry.name))
  sourceAvailable = true
  if (sourceNames.size !== names.size || [...sourceNames].some((name) => !names.has(name))) fail('tracked inventory differs from the available source checkout.')
} catch (error) {
  if (error?.code !== 'ENOENT') throw error
}
console.log(JSON.stringify({ status: 'type-property-inventory-pass', moduleCount: inventory.moduleCount, totals: inventory.totals, sourceAvailable }, null, 2))
