package privatelink

import (
	"context"

	"github.com/tidbcloud/pkgv2/db"
	"go.opentelemetry.io/otel"

	globalngv1 "github.com/tidbcloud/tidb-management-service/api/spec/global/nextgen/v1"
	"github.com/tidbcloud/tidb-management-service/nextgen-global-service/domain/adapter/eventbus"
	"github.com/tidbcloud/tidb-management-service/nextgen-global-service/domain/adapter/regionalserver"
	"github.com/tidbcloud/tidb-management-service/nextgen-global-service/domain/entity"
	"github.com/tidbcloud/tidb-management-service/nextgen-global-service/domain/repository/cluster"
	"github.com/tidbcloud/tidb-management-service/nextgen-global-service/domain/repository/privatelink"
	"github.com/tidbcloud/tidb-management-service/nextgen-global-service/domain/repository/region"
	"github.com/tidbcloud/tidb-management-service/nextgen-global-service/domain/repository/resourcepool"
	"github.com/tidbcloud/tidb-management-service/nextgen-global-service/domain/repository/tidbgroup"
	"github.com/tidbcloud/tidb-management-service/nextgen-global-service/pkg/config"
	"github.com/tidbcloud/tidb-management-service/utilities/bizerr"
	"github.com/tidbcloud/tidb-management-service/utilities/idgenerator"
	"github.com/tidbcloud/tidb-management-service/utilities/workflow"
)

var tracer = otel.Tracer("nextgen-global-service/domain/service/privatelink")

type Service interface {
	CreatePrivateLinkService(
		ctx context.Context,
		req *globalngv1.CreatePrivateLinkServiceRequest,
	) (*entity.PrivateLinkService, bizerr.BizError)
	ListPrivateLinkServices(
		ctx context.Context,
		req *globalngv1.ListPrivateLinkServicesRequest,
	) ([]*entity.PrivateLinkService, bizerr.BizError)
	DeletePrivateLinkService(
		ctx context.Context,
		req *globalngv1.DeletePrivateLinkServiceRequest,
	) bizerr.BizError

	CreatePrivateLinkConnection(
		ctx context.Context,
		req *globalngv1.CreatePrivateLinkConnectionRequest,
	) (*entity.PrivateLinkConnection, bizerr.BizError)
	DeletePrivateLinkConnection(
		ctx context.Context,
		req *globalngv1.DeletePrivateLinkConnectionRequest,
	) (*entity.PrivateLinkConnection, bizerr.BizError)
	GetPrivateLinkConnection(
		ctx context.Context,
		req *globalngv1.GetPrivateLinkConnectionRequest,
	) (*entity.PrivateLinkConnection, bizerr.BizError)
	ListPrivateLinkConnections(
		ctx context.Context,
		req *globalngv1.ListPrivateLinkConnectionsRequest,
	) ([]*entity.PrivateLinkConnection, bizerr.BizError)
}

func NewService(
	cfg *config.Config,
	flow workflow.Workflow,
	transaction db.Transactioner,
	eventCommitter eventbus.WALCommitter,
	regionRepo region.Repo,
	clusterRepo cluster.Repo,
	tidbGroupRepo tidbgroup.Repo,
	privatelinkRepo privatelink.Repo,
	regionalCli regionalserver.Client,
	idGeneratorFacade idgenerator.IDGenerator,
	resourcePoolRepo resourcepool.Repo,
) Service {
	return &service{
		cfg:               cfg,
		flow:              flow,
		transaction:       transaction,
		eventCommitter:    eventCommitter,
		regionRepo:        regionRepo,
		clusterRepo:       clusterRepo,
		tidbGroupRepo:     tidbGroupRepo,
		privatelinkRepo:   privatelinkRepo,
		regionalCli:       regionalCli,
		idGeneratorFacade: idGeneratorFacade,
		resourcePoolRepo:  resourcePoolRepo,
	}
}

type service struct {
	cfg               *config.Config
	flow              workflow.Workflow
	transaction       db.Transactioner
	eventCommitter    eventbus.WALCommitter
	regionRepo        region.Repo
	clusterRepo       cluster.Repo
	tidbGroupRepo     tidbgroup.Repo
	privatelinkRepo   privatelink.Repo
	regionalCli       regionalserver.Client
	idGeneratorFacade idgenerator.IDGenerator
	resourcePoolRepo  resourcepool.Repo
}
