package compat

import (
	"context"
	"errors"

	"gorm.io/gorm"

	globaldedicatedv1 "github.com/tidbcloud/tidb-management-service/api/spec/global/dedicated/v1"
	tidbmgmtservicev1 "github.com/tidbcloud/tidb-management-service/api/spec/tidb_mgmt_service/v1"
	"github.com/tidbcloud/tidb-management-service/tidb-mgmt-service/domain/adapter/dedicatedglobal"
	"github.com/tidbcloud/tidb-management-service/tidb-mgmt-service/domain/repository"
	"github.com/tidbcloud/tidb-management-service/tidb-mgmt-service/pkg/apimiddleware/bizerror"
)

func NewServer(
	dedicatedCli dedicatedglobal.DedicatedGlobal,
	clusterRepo repository.ClusterRepository,
) tidbmgmtservicev1.DataPlaneServiceServer {
	return &serverImpl{
		dedicatedCli: dedicatedCli,
		clusterRepo:  clusterRepo,
	}
}

type serverImpl struct {
	dedicatedCli dedicatedglobal.DedicatedGlobal
	clusterRepo  repository.ClusterRepository
}

func (s serverImpl) GetCompatCluster(
	ctx context.Context,
	request *tidbmgmtservicev1.GetCompatClusterRequest,
) (*globaldedicatedv1.CompatCluster, error) {
	// Check mgmt cluster repo first.
	_, err := s.clusterRepo.GetCluster(ctx, request.GetClusterId(), request.GetShowDeleted())
	if err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return nil, bizerror.NewNotFound(err, "cluster not found")
		}
		return nil, bizerror.NewInternal(err, "failed to get cluster")
	}

	resp, err := s.dedicatedCli.GetCompatCluster(ctx, &globaldedicatedv1.GetCompatClusterRequest{
		ClusterId:   request.GetClusterId(),
		ShowDeleted: request.GetShowDeleted(),
	})
	if err != nil {
		return nil, err
	}
	return resp, nil
}

func (s serverImpl) GetCompatNetwork(
	ctx context.Context,
	request *tidbmgmtservicev1.GetCompatNetworkRequest,
) (*globaldedicatedv1.CompatNetwork, error) {
	resp, err := s.dedicatedCli.GetCompatNetwork(ctx, &globaldedicatedv1.GetCompatNetworkRequest{
		ProjectId:    request.GetProjectId(),
		ProviderName: request.GetProviderName(),
		RegionName:   request.GetRegionName(),
	})
	if err != nil {
		return nil, err
	}
	return resp, nil
}

func (s serverImpl) GetCompatProvider(
	ctx context.Context,
	request *tidbmgmtservicev1.GetCompatProviderRequest,
) (*globaldedicatedv1.CompatProvider, error) {
	resp, err := s.dedicatedCli.GetCompatProvider(ctx, &globaldedicatedv1.GetCompatProviderRequest{
		ProviderName: request.GetProviderName(),
	})
	if err != nil {
		return nil, err
	}
	return resp, nil
}
