package jobs

import (
	"context"

	"github.com/pingcap/log"
	"github.com/tidbcloud/pkgv2/bizerr"
	"github.com/tidbcloud/pkgv2/db"
	"github.com/tidbcloud/serverless-service/internal/controller"
	"github.com/tidbcloud/serverless-service/internal/domain/constant"
	"github.com/tidbcloud/serverless-service/internal/domain/entity"
	"github.com/tidbcloud/serverless-service/internal/domain/facade"
	"github.com/tidbcloud/serverless-service/internal/domain/repo"
	tidbmgmtservicev1 "github.com/tidbcloud/tidb-management-service/api/spec/tidb_mgmt_service/v1"
	"go.uber.org/zap"
)

func SyncClusterRUMode(ctx context.Context) error {
	return controller.DiCall(func(
		mgmtFacade facade.MgmtSvcFacade,
		clusterRepo repo.ClusterRepo,
		dbProvider db.Provider,
	) error {
		var clusters []*entity.Cluster
		if err := dbProvider.ReadDB(ctx).
			Model(&entity.Cluster{}).
			Find(&clusters).Error; err != nil {
			return bizerr.WrapGormError(err, "failed to list clusters")
		}

		for _, cluster := range clusters {
			c, err := mgmtFacade.GetCluster(ctx, cluster.ID, tidbmgmtservicev1.ClusterFilter_CLUSTER_VIEW_BASIC)
			if err != nil {
				log.Error("failed to get cluster from mgmt-svc", zap.Uint64("cluster_id", cluster.ID), zap.Error(err))
				continue
			}

			if c.GetServerlessCluster().GetCluster().GetAnnotations()[constant.AnnoRuLimitMode] == constant.RuLimitModeStandard {
				cluster.RuMode = constant.ClusterRUModeStandard
			} else if c.GetServerlessCluster().GetCluster().GetAnnotations()[constant.AnnoRuLimitMode] == constant.RuLimitModeThrottled {
				cluster.RuMode = constant.ClusterRUModeThrottled
			} else {
				log.Error("unknown ru limit mode", zap.Uint64("cluster_id", cluster.ID))
				continue
			}

			if err := clusterRepo.Save(ctx, cluster); err != nil {
				log.Error("failed to save cluster", zap.Uint64("cluster_id", cluster.ID), zap.Error(err))
			}
		}

		return nil
	})
}
