import { readFile } 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-source-inventory.json'), 'utf8'))
const fail = (message) => { throw new Error(`FreeCAD source 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)
  for (const field of ['sourcePath', 'cmakeOption', 'runtimeStatus']) if (typeof module[field] !== 'string' || !module[field]) fail(`${module.name}.${field} is missing.`)
  if (!Array.isArray(module.commandIds)) fail(`${module.name}.commandIds must be an array.`)
  if (module.commandIds.some((command) => typeof command !== 'string' || !command)) fail(`${module.name} has an invalid command ID.`)
}
const sourceRoot = process.env.FREECAD_SOURCE_DIR
  ? resolve(process.env.FREECAD_SOURCE_DIR)
  : resolve(root, inventory.baseline.sourcePath || '.cache/freecad/FreeCAD')
const sourceMod = resolve(sourceRoot, 'src/Mod')
let sourceAvailable = false
try {
  const entries = await import('node:fs/promises').then(({ readdir }) => readdir(sourceMod, { 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: 'source-inventory-pass', moduleCount: inventory.moduleCount, commandCount: inventory.modules.reduce((total, module) => total + module.commandIds.length, 0), sourceAvailable }, null, 2))

function joinRoot(path) { return resolve(root, path) }
