package app import ( "sort" "strings" ) func dedupeTransportConflicts(in []TransportConflictRecord) []TransportConflictRecord { if len(in) <= 1 { return in } seen := map[string]struct{}{} out := make([]TransportConflictRecord, 0, len(in)) for _, it := range in { key := it.Severity + "|" + it.Type + "|" + it.Key + "|" + strings.Join(it.Owners, ",") if _, ok := seen[key]; ok { continue } seen[key] = struct{}{} out = append(out, it) } sort.Slice(out, func(i, j int) bool { if out[i].Severity != out[j].Severity { return out[i].Severity > out[j].Severity } if out[i].Type != out[j].Type { return out[i].Type < out[j].Type } return out[i].Key < out[j].Key }) return out } func computeTransportPolicyDiff(current, next []TransportPolicyIntent) TransportPolicyDiff { cur := map[string]TransportPolicyIntent{} for _, it := range current { n, key, _, err := normalizeTransportIntent(it) if err != nil || key == "" { continue } cur[key] = n } nxt := map[string]TransportPolicyIntent{} for _, it := range next { n, key, _, err := normalizeTransportIntent(it) if err != nil || key == "" { continue } nxt[key] = n } diff := TransportPolicyDiff{} for k, n := range nxt { c, ok := cur[k] if !ok { diff.Added++ continue } if c.ClientID != n.ClientID || c.Mode != n.Mode || c.Priority != n.Priority { diff.Changed++ } } for k := range cur { if _, ok := nxt[k]; !ok { diff.Removed++ } } return diff } func summarizeTransportConflicts(items []TransportConflictRecord) TransportPolicyValidateSummary { s := TransportPolicyValidateSummary{} for _, it := range items { switch strings.ToLower(strings.TrimSpace(it.Severity)) { case "block": s.BlockCount++ case "warn": s.WarnCount++ } } return s }