package grpcli

import (
	"context"

	"github.com/tidbcloud/dataflow-service/pkg/log"
	"github.com/tidbcloud/pkgv2/bizerr"
	globalv1 "github.com/tidbcloud/tidb-management-service/api/spec/global/dedicated/v1"
	tidb_mgmt_servicev1 "github.com/tidbcloud/tidb-management-service/api/spec/tidb_mgmt_service/v1"
	"go.uber.org/zap"
)

// InternalVPCPeeringGrpcClient only used for vpc peering functions between tidbcloud vpcs on 3-layer arch
type InternalVPCPeeringGrpcClient interface {
	Create(
		ctx context.Context, req *tidb_mgmt_servicev1.CreateVpcPeeringRequest,
	) (peeringID uint64, err bizerr.BizError)
	List(ctx context.Context, req *tidb_mgmt_servicev1.ListVpcPeeringsRequest) ([]*globalv1.VpcPeering, bizerr.BizError)
	Get(ctx context.Context, req *tidb_mgmt_servicev1.GetVpcPeeringRequest) (*globalv1.VpcPeering, bizerr.BizError)
	Delete(ctx context.Context, req *tidb_mgmt_servicev1.DeleteVpcPeeringRequest) bizerr.BizError
}

type internalVPCPeeringGrpcClientImpl struct {
	client tidb_mgmt_servicev1.VpcPeeringServiceClient
}

func NewInternalVPCPeeringGrpcClientImpl(ctx context.Context, addr string) InternalVPCPeeringGrpcClient {
	logger := log.GetLogger(ctx)
	logger.Info("initializing vpc peering service client", zap.String("addr", addr))

	conn := MustBuildGrpcClientConnection(ctx, addr)
	client := tidb_mgmt_servicev1.NewVpcPeeringServiceClient(conn)
	return &internalVPCPeeringGrpcClientImpl{
		client: client,
	}
}

func (m *internalVPCPeeringGrpcClientImpl) Create(
	ctx context.Context, req *tidb_mgmt_servicev1.CreateVpcPeeringRequest,
) (uint64, bizerr.BizError) {
	resp, err := m.client.CreateVpcPeering(ctx, req)
	if err != nil {
		return 0, globalServiceError2BizError(err)
	}
	return resp.PeeringId, nil
}

func (m *internalVPCPeeringGrpcClientImpl) List(
	ctx context.Context, req *tidb_mgmt_servicev1.ListVpcPeeringsRequest,
) ([]*globalv1.VpcPeering, bizerr.BizError) {
	resp, err := m.client.ListVpcPeerings(ctx, req)
	if err != nil {
		return nil, globalServiceError2BizError(err)
	}
	return resp.VpcPeerings, nil
}

func (m *internalVPCPeeringGrpcClientImpl) Get(
	ctx context.Context, req *tidb_mgmt_servicev1.GetVpcPeeringRequest,
) (*globalv1.VpcPeering, bizerr.BizError) {
	resp, err := m.client.GetVpcPeering(ctx, req)
	if err != nil {
		return nil, globalServiceError2BizError(err)
	}
	return resp.VpcPeering, nil
}

func (m *internalVPCPeeringGrpcClientImpl) Delete(
	ctx context.Context, req *tidb_mgmt_servicev1.DeleteVpcPeeringRequest,
) bizerr.BizError {
	_, err := m.client.DeleteVpcPeering(ctx, req)
	if err != nil {
		return globalServiceError2BizError(err)
	}
	return nil
}
