package dbuser

import (
	"context"

	"github.com/tidbcloud/account/internel/svc/dbuser"

	"github.com/tidbcloud/account/central/utils"
	"github.com/tidbcloud/account/commons/config"
	"go.opentelemetry.io/otel"

	"go.uber.org/zap"

	"github.com/tidbcloud/tiinf/monitor/tilog"

	"github.com/tidbcloud/account/internel/dao/entity"
	"github.com/tidbcloud/account/thirdparty/infra"

	dbuserDao "github.com/tidbcloud/account/internel/dao/dbuser"
)

// RunClusterKeyJob
// @Description:push public key to cluster
// @Author wangletian 2022-12-17 23:06:40
// @param ctx
// @param dbUserSrv
// @return error
func RunClusterKeyJob(c context.Context, dbUserSrv dbuser.DBUserIface) error {
	ctx, span := otel.Tracer(config.TraceComponentNameWorker).Start(context.Background(), "RunClusterKeyJob")
	defer span.End()
	bm := utils.Begin(ctx, "RunClusterKeyJob")
	defer bm.OnExit(ctx)
	filter := dbuserDao.CommandClusterKeyFilter{
		Status: []entity.CommandStatus{entity.CommandStatusWaiting, entity.CommandStatusFail},
	}
	objs, err := dbUserSrv.ListCommandClusterKeys(ctx, filter)
	tilog.Info(ctx, "RunOrgKeyJob ListCommandClusterKeys", zap.Any("objs", objs))
	if err != nil {
		tilog.Error(ctx, "ListCommandClusterKeys error", zap.Any("filter", filter), zap.Any("error", err.Error()))
		return err
	}
	for _, c := range objs {
		if !IsIgnore(ctx, c.Status, c.CreatedAt, c) {
			// push key to cm
			if err := pushClusterKey(ctx, dbUserSrv, c); err != nil {
				tilog.Error(ctx, "pushClusterKey error", zap.Error(err))
			}
		}

	}
	return nil

}

// pushClusterKey
//
//	@Description: call cm  push key to cluster
//	@Author wangletian 2022-12-25 23:06:13
//	@param ctx
//	@param svc
//	@param e
//	@return error
func pushClusterKey(ctx context.Context, svc dbuser.DBUserIface, e entity.CommandClusterKey) error {
	keys, err := svc.GetPublicKeysByOrgId(ctx, e.OrgID.Uint64())
	if err != nil {
		tilog.Error(ctx, "pushClusterKey getPublicKeys error", zap.Any("OrgId", e.OrgID), zap.Any("error", err.Error()))
		e.Status = entity.CommandStatusFail
		return svc.UpdateCommandClusterKey(ctx, e)

	}
	status := infra.GetHandler().SetClusterAuthPubKey(ctx, e.ClusterID.Uint64(), keys)
	e.Status = status
	return svc.UpdateCommandClusterKey(ctx, e)

}
