package grpc

import (
	"context"
	"fmt"
	"log"
	"net"

	"github.com/UpmeshLTD/urus-aio/mdm/config"
	"github.com/UpmeshLTD/urus-aio/mdm/server/grpc/pb"
	"github.com/UpmeshLTD/urus-aio/mdm/service"
	"go.opencensus.io/plugin/ocgrpc"
	"google.golang.org/grpc"
)

//go:generate mockery --name=Server --inpackage --case=snake
type Server interface {
	Serve() error
}

func NewServer(
	svc service.Service,
	configProvider config.Config,
) Server {
	return &serverImpl{
		svc:            svc,
		configProvider: configProvider,
	}
}

type serverImpl struct {
	svc            service.Service
	configProvider config.Config
}

func (i *serverImpl) Serve() error {

	conf := i.configProvider.GetGRPCConfig()
	grpcListener, err := net.Listen("tcp", fmt.Sprintf(":%d", conf.Port))
	if err != nil {
		log.Printf("Listen GRPC error: %s", err.Error())
		return err
	}

	s := grpc.NewServer(
		grpc.StatsHandler(
			&ocgrpc.ServerHandler{},
		),
	)

	pb.RegisterMdmServiceServer(s, &mdmServer{
		svc: i.svc,
	})

	log.Printf(" 🚀 Listening GRPC on port %d", conf.Port)
	return s.Serve(grpcListener)
}

type mdmServer struct {
	pb.UnimplementedMdmServiceServer
	svc service.Service
}

func (i *mdmServer) Ping(ctx context.Context, req *pb.PingRequest) (*pb.PingResponse, error) {
	return i.svc.Ping(ctx, req)
}

func (i *mdmServer) GetCountryByID(ctx context.Context, req *pb.GetCountryByIDRequest) (*pb.GetCountryResponse, error) {
	return i.svc.GetCountryByID(ctx, req)
}

func (i *mdmServer) GetCountryByCode(ctx context.Context, req *pb.GetCountryByCodeRequest) (*pb.GetCountryResponse, error) {
	return i.svc.GetCountryByCode(ctx, req)
}

func (i *mdmServer) GetAddressByID(ctx context.Context, req *pb.GetAddressByIDRequest) (*pb.GetAddressByIDResponse, error) {
	return i.svc.GetAddressByID(ctx, req)
}
