package backend

import (
	"context"

	"github.com/tidbcloud/chaos-svc/idl/pbgen/proto/chaos"
	"github.com/tidbcloud/chaos-svc/pkg/domain/facade"
	backendSvc "github.com/tidbcloud/chaos-svc/pkg/domain/service/backend"
	"github.com/tidbcloud/pkgv2/bizerr"
	"github.com/tidbcloud/pkgv2/db"
	"github.com/tidbcloud/pkgv2/log"
)

type EnableBackendSvc struct {
	trans            db.TransProvider
	enableBackendSvc backendSvc.EnableBackendSvc
	infraFacade      facade.Infra
}

func NewEnableBackendSvc(
	trans db.TransProvider,
	enableBackendSvc backendSvc.EnableBackendSvc,
	infraFacade facade.Infra,
) *EnableBackendSvc {
	return &EnableBackendSvc{
		trans:            trans,
		enableBackendSvc: enableBackendSvc,
		infraFacade:      infraFacade,
	}
}

func (svc *EnableBackendSvc) Execute(ctx context.Context, req *chaos.EnableChaosBackendRequest) bizerr.BizError {
	logger := log.WithContextS(ctx).With("clusterID", req.ClusterId).With("projectID", req.ProjectId)
	logger.Info("enable chaos backend")

	tidbCluster, err := svc.infraFacade.GetTiDBCluster(ctx, req.ProjectId, req.ClusterId)
	if err != nil {
		return err
	}
	if err := validateClusterType(tidbCluster); err != nil {
		return err
	}

	if err := svc.trans.Transaction(ctx, func(ctx context.Context) error {
		params, err := buildEnableBackendParams(ctx, req, tidbCluster)
		if err != nil {
			return err
		}

		if err := svc.enableBackendSvc.Execute(ctx, params); err != nil {
			return err
		}
		return nil
	}); err != nil {
		return bizerr.WrapError(err, "transaction")
	}
	return nil
}

func buildEnableBackendParams(ctx context.Context, req *chaos.EnableChaosBackendRequest, cluster *facade.TiDBCluster) (*backendSvc.EnableBackendParam, bizerr.BizError) {
	return &backendSvc.EnableBackendParam{
		ProjectID:    req.ProjectId,
		NetworkName:  cluster.NetworkName,
		Region:       cluster.Region,
		ProviderType: cluster.ProviderType,
		UserID:       req.UserId,
	}, nil
}
