package migrate

import (
	"context"
	"fmt"

	"github.com/tidbcloud/core-svc/model"
	"github.com/tidbcloud/pkgv2/log"
	"github.com/tidbcloud/pkgv2/logid"
	"go.uber.org/zap"
	"gorm.io/gorm"
)

var _ = AddCoreMigrateRecord(
	"202302201419",
	func(db *gorm.DB) error {
		const (
			migrateSnapshotBatchSize = 1000
		)
		ctx := context.Background()
		ctx = logid.WithLogid(ctx, logid.GenLogid())

		logger := log.WithContextS(ctx)

		logger.Infof("begin")
		id := uint64(0)
		for {
			var snapshots []*model.ClusterSnapshot
			if err := db.Model(&model.ClusterSnapshot{}).
				Where("id > ?", id).
				Order("id ASC").
				Limit(migrateSnapshotBatchSize).
				Find(&snapshots).Error; err != nil {
				return fmt.Errorf("find snapshots: %w", err)
			}

			for _, each := range snapshots {
				logger := logger.With(zap.Uint64("cluster_id", each.ClusterID.Uint64()), zap.Uint64("snapshot_id", each.ID.Uint64()))

				amended := false
				var newComponents []model.ComponentState
				for _, component := range each.ComponentStates.Components {
					if component.Replicas == 0 {
						amended = true
						logger.Infof("drop component, component=%+v", component)
						continue
					}

					newComponents = append(newComponents, component)
				}
				each.ComponentStates.Components = newComponents
				if amended {
					if err := db.Save(each).Error; err != nil {
						logger.Errorf("amend snapshot(%+v): %s", each, err)
						continue
					}

					logger.Infof("snapshot amended, id=%d", each.ID)
				} else {
					logger.Infof("no changes, skip, id=%d", each.ID)
				}
			}

			if len(snapshots) < migrateSnapshotBatchSize {
				logger.Infof("all snapshots migrated, done")
				break
			}
			id = snapshots[len(snapshots)-1].ID.Uint64()
		}

		logger.Infof("end")
		return nil
	},
)
