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

const root = resolve(new URL('..', import.meta.url).pathname)
const load = (path) => readFile(resolve(root, path), 'utf8').then(JSON.parse)
const outputPath = resolve(root, 'config/freecad-property-fileincluded-promotion.json')
const [inventory, success, failure, mutation, roundTrip, chrome, semantics, progress] = await Promise.all([
  load('config/freecad-property-fileincluded-inventory.json'),
  load('config/freecad-property-fileincluded-success.json'),
  load('config/freecad-property-fileincluded-failure.json'),
  load('config/freecad-property-fileincluded-mutation.json'),
  load('config/freecad-property-fileincluded-roundtrip.json'),
  load('config/chrome-property-fileincluded-verification.json'),
  load('config/freecad-native-property-semantics.json'),
  load('config/freecad-follow-up-task-progress.json'),
])
const fail = (message) => { throw new Error(`FreeCAD PropertyFileIncluded promotion generation failed: ${message}`) }
const requiredCompletedPhases = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']
const completed = new Map(progress.completedTasks?.map((entry) => [entry.id, entry]) ?? [])
for (const phase of requiredCompletedPhases) if (!completed.has(`PROP-app-propertyfileincluded-${phase}`)) fail(`phase ${phase} is not completed in the evidence ledger`)
if (inventory.status !== 'pass' || inventory.propertyType !== 'App::PropertyFileIncluded' || inventory.recordCount !== 20 || inventory.objectTypeCount !== 15 || inventory.records?.filter(({ valueModel }) => valueModel?.writableByStatus === true).length !== 11) fail('inventory evidence is invalid')
for (const [name, artifact] of Object.entries({ success, failure, mutation, roundTrip, chrome })) if (artifact.status !== 'pass') fail(`${name} evidence is not passing`)
const propertyType = semantics.types?.find(({ typeId }) => typeId === 'App::PropertyFileIncluded')
if (propertyType?.support !== 'native-editable-codec' || propertyType.recordCount !== 20 || propertyType.objectTypeCount !== 15 || propertyType.statusNames?.join(',') !== 'PropOutput,ReadOnly') fail('global property semantics did not promote App::PropertyFileIncluded')
const opaque = semantics.supportSummary?.['opaque-fcstd-proxy']
const editable = semantics.supportSummary?.['native-editable-codec']
if (opaque?.typeCount !== 46 || opaque.recordCount !== 457 || editable?.typeCount !== 34 || editable.recordCount !== 4370) fail('global property support summary is not synchronized')
if (roundTrip.classification?.zeroUnknownDrift !== true || roundTrip.classification.archiveName !== 'payload.bin' || roundTrip.classification.resavedResourceMatches !== true || chrome.persistence?.loadedType !== 'App::PropertyFileIncluded' || chrome.persistence.fcstdElement !== 'FileIncluded' || chrome.persistence.fcstdResourceMatches !== true || chrome.resource?.documentRoundTrip !== true || chrome.resource.independentReleased !== true || chrome.release?.workerTerminated !== true) fail('round-trip or browser closure evidence is incomplete')

const report = {
  schemaVersion: 1,
  status: 'pass',
  taskId: 'PROP-app-propertyfileincluded-I',
  baseline: semantics.baseline,
  propertyType: 'App::PropertyFileIncluded',
  recordCount: 20,
  phaseEvidence: Object.fromEntries(requiredCompletedPhases.map((phase) => [phase, completed.get(`PROP-app-propertyfileincluded-${phase}`).evidence])),
  promotion: {
    from: inventory.classification,
    to: propertyType.support,
    facadeValueModel: 'project-resource-identity-and-authoritative-bytes-with-native-fileincluded-fcstd-resource',
    writableRecords: 11,
    readOnlyRecords: 8,
    outputRecords: 1,
    objectTypeCount: propertyType.objectTypeCount,
    fcstdElement: chrome.persistence.fcstdElement,
    nativeArchiveName: roundTrip.classification.archiveName,
    nativeRoundTripSha256: roundTrip.classification.resavedSha256,
    browserArchiveName: chrome.persistence.fcstdResourcePath,
    browserRoundTripBytes: chrome.persistence.fcstdResourceBytes,
    externalResourceBoundary: roundTrip.classification.externalResourceBoundary,
    zeroUnknownDrift: roundTrip.classification.zeroUnknownDrift,
  },
  exactBlockerSync: {
    nativeEditableTypes: editable.typeCount,
    nativeEditableRecords: editable.recordCount,
    opaqueTypes: opaque.typeCount,
    opaqueRecords: opaque.recordCount,
    exactPromotionReady: semantics.exactPromotionReady,
    exactBlocker: semantics.exactBlocker,
  },
  systemExact: false,
  generatedAt: new Date().toISOString(),
}
await writeFile(outputPath, `${JSON.stringify(report, null, 2)}\n`)
console.log(JSON.stringify({ status: 'freecad-property-fileincluded-promotion-generated', output: 'config/freecad-property-fileincluded-promotion.json', promotion: report.promotion, exactBlockerSync: report.exactBlockerSync }, null, 2))


