package client import ( "context" "crypto/tls" "fmt" "strings" "time" "github.com/tech/sendico/pkg/merrors" methodsv1 "github.com/tech/sendico/pkg/proto/payments/methods/v1" "google.golang.org/grpc" "google.golang.org/grpc/credentials" "google.golang.org/grpc/credentials/insecure" ) // Client exposes typed helpers around the payment methods gRPC API. type Client interface { CreatePaymentMethod(ctx context.Context, req *methodsv1.CreatePaymentMethodRequest) (*methodsv1.CreatePaymentMethodResponse, error) GetPaymentMethod(ctx context.Context, req *methodsv1.GetPaymentMethodRequest) (*methodsv1.GetPaymentMethodResponse, error) UpdatePaymentMethod(ctx context.Context, req *methodsv1.UpdatePaymentMethodRequest) (*methodsv1.UpdatePaymentMethodResponse, error) DeletePaymentMethod(ctx context.Context, req *methodsv1.DeletePaymentMethodRequest) (*methodsv1.DeletePaymentMethodResponse, error) SetPaymentMethodArchived(ctx context.Context, req *methodsv1.SetPaymentMethodArchivedRequest) (*methodsv1.SetPaymentMethodArchivedResponse, error) ListPaymentMethods(ctx context.Context, req *methodsv1.ListPaymentMethodsRequest) (*methodsv1.ListPaymentMethodsResponse, error) Close() error } type grpcPaymentMethodsClient interface { CreatePaymentMethod(ctx context.Context, in *methodsv1.CreatePaymentMethodRequest, opts ...grpc.CallOption) (*methodsv1.CreatePaymentMethodResponse, error) GetPaymentMethod(ctx context.Context, in *methodsv1.GetPaymentMethodRequest, opts ...grpc.CallOption) (*methodsv1.GetPaymentMethodResponse, error) UpdatePaymentMethod(ctx context.Context, in *methodsv1.UpdatePaymentMethodRequest, opts ...grpc.CallOption) (*methodsv1.UpdatePaymentMethodResponse, error) DeletePaymentMethod(ctx context.Context, in *methodsv1.DeletePaymentMethodRequest, opts ...grpc.CallOption) (*methodsv1.DeletePaymentMethodResponse, error) SetPaymentMethodArchived(ctx context.Context, in *methodsv1.SetPaymentMethodArchivedRequest, opts ...grpc.CallOption) (*methodsv1.SetPaymentMethodArchivedResponse, error) ListPaymentMethods(ctx context.Context, in *methodsv1.ListPaymentMethodsRequest, opts ...grpc.CallOption) (*methodsv1.ListPaymentMethodsResponse, error) } type paymentMethodsClient struct { cfg Config conn *grpc.ClientConn client grpcPaymentMethodsClient } // New dials the payment methods endpoint and returns a ready client. func New(ctx context.Context, cfg Config, opts ...grpc.DialOption) (Client, error) { cfg.setDefaults() if strings.TrimSpace(cfg.Address) == "" { return nil, merrors.InvalidArgument("payment-methods: address is required") } dialCtx, cancel := context.WithTimeout(ctx, cfg.DialTimeout) defer cancel() dialOpts := make([]grpc.DialOption, 0, len(opts)+1) dialOpts = append(dialOpts, opts...) if cfg.Insecure { dialOpts = append(dialOpts, grpc.WithTransportCredentials(insecure.NewCredentials())) } else { dialOpts = append(dialOpts, grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{}))) } conn, err := grpc.DialContext(dialCtx, cfg.Address, dialOpts...) if err != nil { return nil, merrors.InternalWrap(err, fmt.Sprintf("payment-methods: dial %s", cfg.Address)) } return &paymentMethodsClient{ cfg: cfg, conn: conn, client: methodsv1.NewPaymentMethodsServiceClient(conn), }, nil } // NewWithClient injects a pre-built payment methods client (useful for tests). func NewWithClient(cfg Config, c grpcPaymentMethodsClient) Client { cfg.setDefaults() return &paymentMethodsClient{ cfg: cfg, client: c, } } func (c *paymentMethodsClient) Close() error { if c.conn != nil { return c.conn.Close() } return nil } func (c *paymentMethodsClient) callContext(ctx context.Context) (context.Context, context.CancelFunc) { timeout := c.cfg.CallTimeout if timeout <= 0 { timeout = 3 * time.Second } return context.WithTimeout(ctx, timeout) } func (c *paymentMethodsClient) CreatePaymentMethod(ctx context.Context, req *methodsv1.CreatePaymentMethodRequest) (*methodsv1.CreatePaymentMethodResponse, error) { callCtx, cancel := c.callContext(ctx) defer cancel() return c.client.CreatePaymentMethod(callCtx, req) } func (c *paymentMethodsClient) GetPaymentMethod(ctx context.Context, req *methodsv1.GetPaymentMethodRequest) (*methodsv1.GetPaymentMethodResponse, error) { callCtx, cancel := c.callContext(ctx) defer cancel() return c.client.GetPaymentMethod(callCtx, req) } func (c *paymentMethodsClient) UpdatePaymentMethod(ctx context.Context, req *methodsv1.UpdatePaymentMethodRequest) (*methodsv1.UpdatePaymentMethodResponse, error) { callCtx, cancel := c.callContext(ctx) defer cancel() return c.client.UpdatePaymentMethod(callCtx, req) } func (c *paymentMethodsClient) DeletePaymentMethod(ctx context.Context, req *methodsv1.DeletePaymentMethodRequest) (*methodsv1.DeletePaymentMethodResponse, error) { callCtx, cancel := c.callContext(ctx) defer cancel() return c.client.DeletePaymentMethod(callCtx, req) } func (c *paymentMethodsClient) SetPaymentMethodArchived(ctx context.Context, req *methodsv1.SetPaymentMethodArchivedRequest) (*methodsv1.SetPaymentMethodArchivedResponse, error) { callCtx, cancel := c.callContext(ctx) defer cancel() return c.client.SetPaymentMethodArchived(callCtx, req) } func (c *paymentMethodsClient) ListPaymentMethods(ctx context.Context, req *methodsv1.ListPaymentMethodsRequest) (*methodsv1.ListPaymentMethodsResponse, error) { callCtx, cancel := c.callContext(ctx) defer cancel() return c.client.ListPaymentMethods(callCtx, req) }