package server

import (
	"github.com/UpmeshLTD/urus-aio/infrastructure/broker"
	"github.com/UpmeshLTD/urus-aio/shipment/config"
	"github.com/UpmeshLTD/urus-aio/shipment/log"
	"github.com/UpmeshLTD/urus-aio/shipment/server/grpc"
	"github.com/UpmeshLTD/urus-aio/shipment/server/http"
	"github.com/UpmeshLTD/urus-aio/shipment/service"
)

// Server represents the abstraction of the component that hosts transport and service.
//go:generate mockery --name=Server --case=snake
type Server interface {
	StartGRPC() error
	StartHTTP() error
	StartBroker() error
}

// serverImpl implements the Server interface.
type serverImpl struct {
	logger         log.Logger
	configProvider config.Config
	service        service.Service

	grpcServer   grpc.Server
	httpServer   http.Server
	brokerServer broker.MessageBroker
}

func NewServer(
	logger log.Logger,
	configProvider config.Config,
	shipmentService service.Service,
	broker broker.MessageBroker,
) Server {
	return &serverImpl{
		grpcServer:     grpc.NewServer(shipmentService, configProvider, logger),
		httpServer:     http.NewServer(shipmentService, configProvider, logger),
		brokerServer:   broker,
		logger:         logger,
		configProvider: configProvider,
		service:        shipmentService,
	}
}

func (s *serverImpl) StartGRPC() error {
	return s.grpcServer.Serve()
}

func (s *serverImpl) StartHTTP() error {
	return s.httpServer.Serve()
}

func (s *serverImpl) StartBroker() error {
	s.brokerServer.Start()
	return nil
}
