package grpc

import (
	"context"
	"fmt"
	"github.com/UpmeshLTD/urus-aio/service-template/config"
	"github.com/UpmeshLTD/urus-aio/service-template/server/grpc/pb"
	"github.com/UpmeshLTD/urus-aio/service-template/service"
	"go.opencensus.io/plugin/ocgrpc"
	"google.golang.org/grpc"
	"log"
	"net"
)

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

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

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

func (i *serverImpl) Serve() error {

	conf := i.cfg.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{},
		),
	)

	// TODO: change Register function after gen proto (if need)
	pb.RegisterServiceTemplateServiceServer(s, &server{
		svc: i.svc,
	})

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

type server struct {
	pb.UnimplementedServiceTemplateServiceServer // TODO: change this after gen proto (if need)
	svc service.Service
}

// TODO: add RPC endpoints here
func (i *server) Ping(ctx context.Context, req *pb.PingRequest) (*pb.PingResponse, error) {
	return i.svc.Ping(ctx, req)
}
