import fs from 'node:fs'
import crypto from 'node:crypto'
const sourcePath='contracts/integrations/kbx.integrations.json'
const text=fs.readFileSync(sourcePath,'utf8')
const source=JSON.parse(text)
const sha=crypto.createHash('sha256').update(text).digest('hex')
const ids=new Set()
for(const item of source.integrations??[]){
  if(ids.has(item.id)) throw new Error(`duplicate integration id: ${item.id}`)
  ids.add(item.id)
}
const manifest={schemaVersion:source.schemaVersion,integrationVersion:source.integrationVersion,sourceSha256:sha,principles:source.principles,states:source.states,integrations:source.integrations}
fs.mkdirSync('generated',{recursive:true});fs.writeFileSync('generated/integration-manifest.json',JSON.stringify(manifest,null,2)+'\n')
const catalog=Object.fromEntries(source.integrations.map(x=>[x.id,x]))
fs.mkdirSync('packages/kbx-contracts/src/generated',{recursive:true})
fs.writeFileSync('packages/kbx-contracts/src/generated/integrationCatalog.ts',`// generated from ${sourcePath}; do not edit.\nimport type { KbxIntegrationDefinition } from '../integration'\nexport const kbxIntegrationSourceSha256 = '${sha}' as const\nexport const kbxIntegrationCatalog = ${JSON.stringify(catalog,null,2)} as const satisfies Record<string,KbxIntegrationDefinition>\nexport type KbxIntegrationId = keyof typeof kbxIntegrationCatalog\n`)
const esc=s=>String(s).replaceAll('\\','\\\\').replaceAll('"','\\"')
const rows=source.integrations.map(x=>`        new("${esc(x.id)}", "${esc(x.title)}", "${x.ownerModule}", "${x.direction}", "${x.transport}", "${x.criticality}", "${esc(x.sourceEvent)}", "${esc(x.target)}", "${x.delivery}", "${x.ordering}", "${x.idempotency}", ${x.timeoutMs}, ${x.shortRetry.maxRetryAttempts}, ${x.shortRetry.baseDelayMs}, "${x.shortRetry.backoff}", ${x.longRetry.maxAttempts}, new[] { ${x.longRetry.scheduleSeconds.join(', ')} }, ${x.circuitBreaker.failureRatio}, ${x.circuitBreaker.samplingSeconds}, ${x.circuitBreaker.minimumThroughput}, ${x.circuitBreaker.breakSeconds}, "${x.terminalAction}", ${x.userVisible?'true':'false'})`).join(',\n')
fs.mkdirSync('backend/Shared/Integrations/Generated',{recursive:true})
fs.writeFileSync('backend/Shared/Integrations/Generated/KbxIntegrationCatalog.g.cs',`// generated from ${sourcePath}; do not edit.\nnamespace Kbx.Shared.Integrations.Generated;\npublic sealed record KbxIntegrationDefinition(string Id,string Title,string OwnerModule,string Direction,string Transport,string Criticality,string SourceEvent,string Target,string Delivery,string Ordering,string Idempotency,int TimeoutMs,int ShortRetryAttempts,int ShortRetryBaseDelayMs,string ShortRetryBackoff,int LongRetryAttempts,IReadOnlyList<int> LongRetryScheduleSeconds,double CircuitFailureRatio,int CircuitSamplingSeconds,int CircuitMinimumThroughput,int CircuitBreakSeconds,string TerminalAction,bool UserVisible);\npublic static class KbxIntegrationCatalog\n{\n    public const string SourceSha256 = "${sha}";\n    public static readonly IReadOnlyDictionary<string,KbxIntegrationDefinition> All = new Dictionary<string,KbxIntegrationDefinition>(StringComparer.Ordinal)\n    {\n${source.integrations.map(x=>`        ["${esc(x.id)}"] = new("${esc(x.id)}", "${esc(x.title)}", "${x.ownerModule}", "${x.direction}", "${x.transport}", "${x.criticality}", "${esc(x.sourceEvent)}", "${esc(x.target)}", "${x.delivery}", "${x.ordering}", "${x.idempotency}", ${x.timeoutMs}, ${x.shortRetry.maxRetryAttempts}, ${x.shortRetry.baseDelayMs}, "${x.shortRetry.backoff}", ${x.longRetry.maxAttempts}, new[] { ${x.longRetry.scheduleSeconds.join(', ')} }, ${x.circuitBreaker.failureRatio}, ${x.circuitBreaker.samplingSeconds}, ${x.circuitBreaker.minimumThroughput}, ${x.circuitBreaker.breakSeconds}, "${x.terminalAction}", ${x.userVisible?'true':'false'})`).join(',\n')}\n    };\n}\n`)
console.log(`integration contracts generated: ${source.integrations.length}, SHA ${sha.slice(0,12)}`)
