import fs from 'node:fs'
import crypto from 'node:crypto'
const sourcePath='contracts/telemetry/kbx.telemetry.json'
const source=fs.readFileSync(sourcePath,'utf8')
const data=JSON.parse(source)
const sha=crypto.createHash('sha256').update(source).digest('hex')
const names=new Set(), allowedName=/^[a-z][a-z0-9_.-]+$/
for(const event of data.events){
  if(!allowedName.test(event.name)) throw new Error(`invalid telemetry event name: ${event.name}`)
  if(names.has(event.name)) throw new Error(`duplicate telemetry event: ${event.name}`)
  names.add(event.name)
  const attrs=new Set()
  for(const key of event.allowedAttributes??[]){if(attrs.has(key))throw new Error(`duplicate attribute ${event.name}.${key}`);attrs.add(key)}
}
const manifest={schemaVersion:data.schemaVersion,telemetryVersion:data.telemetryVersion,sourceSha256:sha,principles:data.principles,events:data.events,metrics:data.metrics}
fs.mkdirSync('generated',{recursive:true});fs.writeFileSync('generated/telemetry-manifest.json',JSON.stringify(manifest,null,2)+'\n')
const ts=`// generated from ${sourcePath}; do not edit.\nexport const kbxTelemetryCatalog = ${JSON.stringify(Object.fromEntries(data.events.map(e=>[e.name,e])),null,2)} as const\nexport type KbxTelemetryEventName = keyof typeof kbxTelemetryCatalog\nexport const kbxUxMetricCatalog = ${JSON.stringify(Object.fromEntries(data.metrics.map(m=>[m.key,m])),null,2)} as const\nexport type KbxUxMetricKey = keyof typeof kbxUxMetricCatalog\nexport const kbxTelemetrySourceSha256 = '${sha}' as const\n`
fs.mkdirSync('packages/kbx-contracts/src/generated',{recursive:true});fs.writeFileSync('packages/kbx-contracts/src/generated/telemetryCatalog.ts',ts)
const esc=s=>s.replaceAll('"','\\"')
const csEvents=data.events.map(e=>`        ["${e.name}"] = new("${e.name}", "${e.category}", new[] { ${(e.allowedAttributes??[]).map(x=>`"${x}"`).join(', ')} }, ${e.requiresDuration?'true':'false'})`).join(',\n')
const cs=`// generated from ${sourcePath}; do not edit.\nnamespace Kbx.Shared.Telemetry.Generated;\n\npublic sealed record KbxTelemetryEventDefinition(string Name,string Category,IReadOnlyList<string> AllowedAttributes,bool RequiresDuration);\n\npublic static class KbxTelemetryCatalog\n{\n    public const string SourceSha256 = "${sha}";\n    public static readonly IReadOnlyDictionary<string,KbxTelemetryEventDefinition> Events = new Dictionary<string,KbxTelemetryEventDefinition>(StringComparer.Ordinal)\n    {\n${csEvents}\n    };\n}\n`
fs.mkdirSync('backend/Shared/Telemetry/Generated',{recursive:true});fs.writeFileSync('backend/Shared/Telemetry/Generated/KbxTelemetryCatalog.g.cs',cs)
console.log(`generated telemetry contracts: ${data.events.length} events, ${data.metrics.length} metrics`)
