package routers

import (
	"context"
	"net"

	"github.com/tech/sendico/pkg/api/routers/internal/grpcimp"
	"github.com/tech/sendico/pkg/mlogger"
	"google.golang.org/grpc"
)

type (
	GRPCServiceRegistration = func(grpc.ServiceRegistrar)
)

type GRPC interface {
	Register(registration GRPCServiceRegistration) error
	Start(ctx context.Context) error
	Finish(ctx context.Context) error
	Addr() net.Addr
	Done() <-chan error
}

type (
	GRPCConfig    = grpcimp.Config
	GRPCTLSConfig = grpcimp.TLSConfig
)

type GRPCOption func(*grpcimp.Options)

func WithUnaryInterceptors(interceptors ...grpc.UnaryServerInterceptor) GRPCOption {
	return func(o *grpcimp.Options) {
		o.UnaryInterceptors = append(o.UnaryInterceptors, interceptors...)
	}
}

func WithStreamInterceptors(interceptors ...grpc.StreamServerInterceptor) GRPCOption {
	return func(o *grpcimp.Options) {
		o.StreamInterceptors = append(o.StreamInterceptors, interceptors...)
	}
}

func WithListener(listener net.Listener) GRPCOption {
	return func(o *grpcimp.Options) {
		o.Listener = listener
	}
}

func WithServerOptions(opts ...grpc.ServerOption) GRPCOption {
	return func(o *grpcimp.Options) {
		o.ServerOptions = append(o.ServerOptions, opts...)
	}
}

func NewGRPCRouter(logger mlogger.Logger, config *GRPCConfig, opts ...GRPCOption) (GRPC, error) {
	options := &grpcimp.Options{}
	for _, opt := range opts {
		opt(options)
	}
	return grpcimp.NewRouter(logger, config, options)
}
