import fs from 'node:fs'
import crypto from 'node:crypto'
const sourcePath='contracts/providers/kbx.providers.json'
const text=fs.readFileSync(sourcePath,'utf8')
const source=JSON.parse(text)
const sha=crypto.createHash('sha256').update(text).digest('hex')
const seen=new Set()
for(const p of source.providers??[]){if(seen.has(p.id))throw new Error(`duplicate provider ${p.id}`);seen.add(p.id)}
const manifest={schemaVersion:source.schemaVersion,providerVersion:source.providerVersion,sourceSha256:sha,principles:source.principles,providers:source.providers}
fs.mkdirSync('generated',{recursive:true});fs.writeFileSync('generated/provider-manifest.json',JSON.stringify(manifest,null,2)+'\n')
const catalog=Object.fromEntries(source.providers.map(x=>[x.id,x]))
fs.mkdirSync('packages/kbx-contracts/src/generated',{recursive:true})
fs.writeFileSync('packages/kbx-contracts/src/generated/providerCatalog.ts',`// generated from ${sourcePath}; do not edit.\nimport type { KbxExternalProviderDefinition } from '../provider'\nexport const kbxProviderSourceSha256='${sha}' as const\nexport const kbxExternalProviderCatalog=${JSON.stringify(catalog,null,2)} as const satisfies Record<string,KbxExternalProviderDefinition>\nexport type KbxExternalProviderId=keyof typeof kbxExternalProviderCatalog\n`)
const esc=s=>String(s).replaceAll('\\','\\\\').replaceAll('"','\\"')
fs.mkdirSync('backend/Shared/Providers/Generated',{recursive:true})
const rows=source.providers.map(p=>`        ["${esc(p.id)}"] = new("${esc(p.id)}", "${esc(p.title)}", "${p.ownerModule}", "${p.purpose}", ${p.mutationAllowed?'true':'false'}, new[] { ${p.officialSources.map(x=>`"${esc(x)}"`).join(', ')} })`).join(',\n')
fs.writeFileSync('backend/Shared/Providers/Generated/KbxExternalProviderCatalog.g.cs',`// generated from ${sourcePath}; do not edit.\nnamespace Kbx.Shared.Providers.Generated;\npublic sealed record KbxExternalProviderDefinition(string Id,string Title,string OwnerModule,string Purpose,bool MutationAllowed,IReadOnlyList<string> OfficialSources);\npublic static class KbxExternalProviderCatalog { public const string SourceSha256="${sha}"; public static readonly IReadOnlyDictionary<string,KbxExternalProviderDefinition> All=new Dictionary<string,KbxExternalProviderDefinition>(StringComparer.Ordinal) {\n${rows}\n    }; }\n`)
console.log(`provider contracts generated: ${source.providers.length}, SHA ${sha.slice(0,12)}`)
