package quotation import ( "context" "sort" "strings" "github.com/tech/sendico/payments/storage/model" "github.com/tech/sendico/pkg/mlogger" ) type gatewayRegistry struct { logger mlogger.Logger static []*model.GatewayInstanceDescriptor } // NewGatewayRegistry aggregates static gateway descriptors. func NewGatewayRegistry(logger mlogger.Logger, static []*model.GatewayInstanceDescriptor) GatewayRegistry { if len(static) == 0 { return nil } if logger != nil { logger = logger.Named("gateway_registry") } return &gatewayRegistry{ logger: logger, static: cloneGatewayDescriptors(static), } } func (r *gatewayRegistry) List(ctx context.Context) ([]*model.GatewayInstanceDescriptor, error) { items := map[string]*model.GatewayInstanceDescriptor{} for _, gw := range r.static { if gw == nil { continue } id := strings.TrimSpace(gw.ID) if id == "" { continue } items[id] = cloneGatewayDescriptor(gw) } result := make([]*model.GatewayInstanceDescriptor, 0, len(items)) for _, gw := range items { result = append(result, gw) } sort.Slice(result, func(i, j int) bool { return result[i].ID < result[j].ID }) return result, nil } func normalizeCurrencies(values []string) []string { if len(values) == 0 { return nil } seen := map[string]bool{} result := make([]string, 0, len(values)) for _, value := range values { clean := strings.ToUpper(strings.TrimSpace(value)) if clean == "" || seen[clean] { continue } seen[clean] = true result = append(result, clean) } return result } func cloneGatewayDescriptors(src []*model.GatewayInstanceDescriptor) []*model.GatewayInstanceDescriptor { if len(src) == 0 { return nil } result := make([]*model.GatewayInstanceDescriptor, 0, len(src)) for _, item := range src { if item == nil { continue } if cloned := cloneGatewayDescriptor(item); cloned != nil { result = append(result, cloned) } } return result } func cloneGatewayDescriptor(src *model.GatewayInstanceDescriptor) *model.GatewayInstanceDescriptor { if src == nil { return nil } dst := *src if src.Currencies != nil { dst.Currencies = append([]string(nil), src.Currencies...) } dst.Limits = cloneLimits(src.Limits) return &dst } func cloneLimits(src model.Limits) model.Limits { dst := src if src.VolumeLimit != nil { dst.VolumeLimit = map[string]string{} for key, value := range src.VolumeLimit { dst.VolumeLimit[key] = value } } if src.VelocityLimit != nil { dst.VelocityLimit = map[string]int{} for key, value := range src.VelocityLimit { dst.VelocityLimit[key] = value } } if src.CurrencyLimits != nil { dst.CurrencyLimits = map[string]model.LimitsOverride{} for key, value := range src.CurrencyLimits { dst.CurrencyLimits[key] = value } } return dst }