package privatelink

import (
	"context"

	"github.com/samber/lo"
	"google.golang.org/protobuf/types/known/emptypb"

	globalngv1 "github.com/tidbcloud/tidb-management-service/api/spec/global/nextgen/v1"
	"github.com/tidbcloud/tidb-management-service/nextgen-global-service/domain/entity"
	"github.com/tidbcloud/tidb-management-service/nextgen-global-service/domain/service/privatelink"
)

func NewServer(
	svc privatelink.Service,
) globalngv1.PrivateLinkConnectionServiceServer {
	return &server{
		Service: svc,
	}
}

type server struct {
	privatelink.Service
}

func (s *server) CreatePrivateLinkService(
	ctx context.Context,
	req *globalngv1.CreatePrivateLinkServiceRequest,
) (*globalngv1.PrivateLinkService, error) {
	service, err := s.Service.CreatePrivateLinkService(ctx, req)
	if err != nil {
		return nil, err
	}
	return service.PrivateLinkService, nil
}

func (s *server) ListPrivateLinkServices(
	ctx context.Context,
	req *globalngv1.ListPrivateLinkServicesRequest,
) (*globalngv1.ListPrivateLinkServicesResponse, error) {
	services, err := s.Service.ListPrivateLinkServices(ctx, req)
	if err != nil {
		return nil, err
	}
	outputs := lo.Map(services, func(service *entity.PrivateLinkService, _ int) *globalngv1.PrivateLinkService {
		return service.PrivateLinkService
	})
	return &globalngv1.ListPrivateLinkServicesResponse{
		PrivateLinkServices: outputs,
	}, nil
}

func (s *server) DeletePrivateLinkService(ctx context.Context, req *globalngv1.DeletePrivateLinkServiceRequest) (*emptypb.Empty, error) {
	if err := s.Service.DeletePrivateLinkService(ctx, req); err != nil {
		return nil, err
	}
	return &emptypb.Empty{}, nil
}

func (s *server) CreatePrivateLinkConnection(
	ctx context.Context,
	req *globalngv1.CreatePrivateLinkConnectionRequest,
) (*globalngv1.PrivateLinkConnection, error) {
	connection, err := s.Service.CreatePrivateLinkConnection(ctx, req)
	if err != nil {
		return nil, err
	}
	return connection.PrivateLinkConnection, nil
}

func (s *server) DeletePrivateLinkConnection(
	ctx context.Context,
	req *globalngv1.DeletePrivateLinkConnectionRequest,
) (*globalngv1.PrivateLinkConnection, error) {
	connection, err := s.Service.DeletePrivateLinkConnection(ctx, req)
	if err != nil {
		return nil, err
	}
	return connection.PrivateLinkConnection, nil
}

func (s *server) GetPrivateLinkConnection(
	ctx context.Context,
	req *globalngv1.GetPrivateLinkConnectionRequest,
) (*globalngv1.PrivateLinkConnection, error) {
	connection, err := s.Service.GetPrivateLinkConnection(ctx, req)
	if err != nil {
		return nil, err
	}
	return connection.PrivateLinkConnection, nil
}

func (s *server) ListPrivateLinkConnections(
	ctx context.Context,
	req *globalngv1.ListPrivateLinkConnectionsRequest,
) (*globalngv1.ListPrivateLinkConnectionsResponse, error) {
	connections, err := s.Service.ListPrivateLinkConnections(ctx, req)
	if err != nil {
		return nil, err
	}
	outputs := lo.Map(
		connections,
		func(connection *entity.PrivateLinkConnection, _ int) *globalngv1.PrivateLinkConnection {
			return connection.PrivateLinkConnection
		},
	)
	return &globalngv1.ListPrivateLinkConnectionsResponse{
		PrivateLinkConnections: outputs,
	}, nil
}
