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

const root = resolve(new URL('..', import.meta.url).pathname)
const [inventory, contextBoundaries] = await Promise.all([
  readFile(resolve(root, 'config/freecad-gui-command-inventory.json'), 'utf8').then(JSON.parse),
  readFile(resolve(root, 'config/freecad-gui-command-context-boundaries.json'), 'utf8').then(JSON.parse),
])
const fail = (message) => { throw new Error(`FreeCAD GUI command inventory: ${message}`) }
if (inventory.schemaVersion !== 1 || inventory.baseline?.freecadVersion !== '1.1.1' || inventory.baseline?.commit !== '0108fd4b4850cc46e625b60e53cea7a7bbe69f8d') fail('baseline mismatch.')
if (!Number.isInteger(inventory.commandCount) || inventory.commandCount < 900 || !Array.isArray(inventory.commands) || inventory.commands.length !== inventory.commandCount) fail('runtime command inventory is incomplete.')
if (inventory.contextBoundaries !== 'config/freecad-gui-command-context-boundaries.json') fail('context-only command boundary ledger is not linked.')
if (inventory.runtimeEvidence?.report !== '.cache/freecad/reference-desktop-gui-commands.json' || !/^[0-9a-f]{64}$/.test(inventory.runtimeEvidence.reportSha256 || '')) fail('dedicated runtime GUI oracle provenance is incomplete.')
if (inventory.runtimeEvidence?.stateProbe !== 'native-is-active-after-workbench-registration-with-Std_Expressions-qaction-guard' || inventory.runtimeEvidence.stateCases?.join(',') !== 'noDocument,documentNoSelection,selectedPartBox' || inventory.runtimeEvidence.directIsActiveBoundary !== 'Std_Expressions-only-qaction-guard-for-locked-1.1.1-null-qaction-crash') fail('runtime command state boundary is incomplete.')
const ids = new Set()
for (const command of inventory.commands) {
  if (!command.id || ids.has(command.id)) fail(`duplicate or empty command '${command.id}'.`)
  ids.add(command.id)
  if (!Array.isArray(command.sourceModules) || command.sourceModules.length === 0 || !Array.isArray(command.workbenches) || command.workbenches.length === 0) fail(`${command.id} is missing source/workbench ownership.`)
  for (const caseName of ['noDocument', 'documentNoSelection', 'selectedPartBox']) {
    const probeCase = command.cases?.[caseName]
    if (!probeCase?.observed || !Array.isArray(probeCase.states) || probeCase.states.length === 0) fail(`${command.id} is missing ${caseName} evidence.`)
    if (probeCase.states.some((state) => !['true', 'false', 'error', 'no-action'].includes(String(state)))) fail(`${command.id} has an invalid ${caseName} state.`)
  }
}
if (!Array.isArray(inventory.sourceOnlyCommands)) fail('sourceOnlyCommands must be an array.')
const sourceOnlyIds = new Set()
for (const command of inventory.sourceOnlyCommands) {
  if (!command.id || !Array.isArray(command.sourceModules) || !command.reason) fail('source-only command entry is incomplete.')
  if (ids.has(command.id) || sourceOnlyIds.has(command.id)) fail(`source-only command '${command.id}' is duplicated or also runtime-probed.`)
  if (!['module-not-built', 'source-registration-not-loaded'].includes(command.reason)) fail(`source-only command '${command.id}' has an unknown generator reason.`)
  sourceOnlyIds.add(command.id)
}
if (contextBoundaries.schemaVersion !== 1 || contextBoundaries.baseline?.freecadVersion !== '1.1.1' || contextBoundaries.baseline.commit !== inventory.baseline.commit) fail('context-only command boundary baseline mismatch.')
const isolated = contextBoundaries.isolatedWorkbenchOracle
if (isolated?.report !== inventory.runtimeEvidence.report || isolated.reportSha256 !== inventory.runtimeEvidence.reportSha256 || isolated.commandCount !== inventory.commandCount || isolated.commandUniverseSha256 !== '82901c576ef4b4cea1182f6505f5282a70b84ee8420105e83e58f65c0fb9685f' || isolated.shardCount !== 100 || isolated.bimFirstTimeWelcome !== 'suppressed-before-workbench-activation') fail('isolated workbench oracle boundary is incomplete.')
const contextCommands = contextBoundaries.contextOnlyCommands
if (!Array.isArray(contextCommands) || contextCommands.map((command) => command.id).join(',') !== 'Import_ReadBREP,NaviCubeDraggableCmd') fail('context-only command set changed without review.')
for (const command of contextCommands) {
  if (ids.has(command.id) || sourceOnlyIds.has(command.id)) fail(`context-only command '${command.id}' leaked into a startup inventory.`)
  if (!['explicit-module-import-command', 'context-menu-lazy-command'].includes(command.classification) || !command.runtimeExpectation || !command.exactTask || !Array.isArray(command.sourceEvidence) || command.sourceEvidence.length === 0) fail(`context-only command '${command.id}' lacks a complete boundary.`)
}
console.log(JSON.stringify({ status: 'gui-command-inventory-pass', commandCount: inventory.commandCount, sourceOnlyCount: inventory.sourceOnlyCommands.length, contextOnlyCount: contextCommands.length, workbenchCount: inventory.runtimeEvidence?.workbenchCount, documentSensitiveCount: inventory.commands.filter((command) => command.documentSensitive).length, selectionSensitiveCount: inventory.commands.filter((command) => command.selectionSensitive).length }, null, 2))
