package handle

import (
	"context"
	"fmt"
	"os"
	"time"

	"github.com/pingcap/log"
	"github.com/tidbcloud/aws-shared-provider/pkg/datacleaner/common"
	"go.uber.org/zap"
)

func DeleteKeyspaceRegionLabel(ctx context.Context,
	regionLabelRules map[string]*common.RegionLabelRule, pdctx *common.PdContext,
	record *common.KeyspaceRecord, isRun, isSkipConfirm bool) (successed bool, err error) {
	keyspaceId := fmt.Sprintf("%d", record.KeyspaceId)
	if rule, ok := regionLabelRules[keyspaceId]; ok {
		log.Info("[BEGIN] gc region labels", zap.String("keyspaceId", keyspaceId))
		if err = common.DeleteRegionLabel(ctx, pdctx, rule.ID, isRun, isSkipConfirm); err != nil {
			log.Error("Delete region label failed", zap.String("regionLabelID", rule.ID), zap.Error(err))
		} else if isRun {
			log.Info("Delete region label success", zap.String("keyspaceID", keyspaceId))
		}
	} else {
		log.Info("Can't find region label", zap.String("KeyspaceID", keyspaceId))
	}

	if err == nil && isRun {
		record.ArchivedRegionLabel = true
		successed = true
	}
	return
}

func LoadRegionLablesAndGC(ctx context.Context, regionLabelfile,
	archiveKeyspaceFile *os.File, pdctx *common.PdContext, isRun, isSkipConfirm bool, keyspaceInterval time.Duration) error {
	keyspaceRecords, err := common.CacheArchiveKeyspaceRecords(archiveKeyspaceFile)
	if err != nil {
		log.Error("Failed to cache archived keyspace records", zap.Error(err))
		return err
	}
	regionLabelRules, err := common.CacheRegionLabelRules(regionLabelfile)
	if err != nil {
		log.Error("Failed to cache archived region label rules", zap.Error(err))
		return err
	}

	failedKsCt := 0
	successedKsCt := 0
	totalKsArchive := 0
	for _, record := range keyspaceRecords {
		totalKsArchive++
		successed, err := DeleteKeyspaceRegionLabel(ctx, regionLabelRules, pdctx, record, isRun, isSkipConfirm)
		if err != nil {
			failedKsCt++
		}
		if successed {
			successedKsCt++
		}
		if totalKsArchive < len(keyspaceRecords) {
			waitBetweenKeyspaces(keyspaceInterval)
		}
	}

	err = common.UpdateArchiveKeyspaceRecords(keyspaceRecords, archiveKeyspaceFile)
	if err != nil {
		log.Error("Failed to update archived keyspace records", zap.Error(err))
		return err
	}

	log.Info("GC region labels end.",
		zap.Int("totalKsArchive", totalKsArchive),
		zap.Int("failedKsCt", failedKsCt),
		zap.Int("successedKsCt", successedKsCt))

	return nil
}

func DumpAllRegionLabelRules(ctx context.Context, pdctx *common.PdContext, f *os.File) error {
	rules, err := common.GetAllRegionLabelRules(ctx, pdctx)
	if err != nil {
		return err
	}
	return rules.WriteTo(f)
}
