using System; using System.Collections.Generic; using System.Text; namespace StellaOps.Provcache; public sealed partial class VeriKeyBuilder { /// /// Builds the final VeriKey by hashing all components together. /// /// The computed VeriKey in format "sha256:<hex>". /// If required components are missing. public string Build() { ValidateRequiredComponents(); var components = new StringBuilder(); components.Append("v1|"); components.Append(_sourceHash); components.Append('|'); components.Append(_sbomHash); components.Append('|'); components.Append(_vexHashSetHash); components.Append('|'); components.Append(_mergePolicyHash); components.Append('|'); components.Append(_signerSetHash); components.Append('|'); components.Append(_timeWindow); var compositeBytes = Encoding.UTF8.GetBytes(components.ToString()); return ComputeHash(compositeBytes); } /// /// Builds a record with all individual components. /// Useful for debugging and serialization. /// /// A record containing all VeriKey components. public VeriKeyComponents BuildWithComponents() { ValidateRequiredComponents(); return new VeriKeyComponents { VeriKey = Build(), SourceHash = _sourceHash!, SbomHash = _sbomHash!, VexHashSetHash = _vexHashSetHash!, MergePolicyHash = _mergePolicyHash!, SignerSetHash = _signerSetHash!, TimeWindow = _timeWindow! }; } /// /// Resets the builder to its initial state. /// /// This builder for fluent chaining. public VeriKeyBuilder Reset() { _sourceHash = null; _sbomHash = null; _vexHashSetHash = null; _mergePolicyHash = null; _signerSetHash = null; _timeWindow = null; return this; } private void ValidateRequiredComponents() { var missing = new List(); if (string.IsNullOrWhiteSpace(_sourceHash)) missing.Add("SourceHash"); if (string.IsNullOrWhiteSpace(_sbomHash)) missing.Add("SbomHash"); if (string.IsNullOrWhiteSpace(_vexHashSetHash)) missing.Add("VexHashSetHash"); if (string.IsNullOrWhiteSpace(_mergePolicyHash)) missing.Add("MergePolicyHash"); if (string.IsNullOrWhiteSpace(_signerSetHash)) missing.Add("SignerSetHash"); if (string.IsNullOrWhiteSpace(_timeWindow)) missing.Add("TimeWindow"); if (missing.Count > 0) { throw new InvalidOperationException( $"Cannot build VeriKey: missing required components: {string.Join(", ", missing)}. " + "Use the With* methods to set all required components before calling Build()."); } } }