package br

import (
	"context"
	"strconv"

	eventdata "github.com/tidbcloud/eventbus-datastruct/event"
	"github.com/tidbcloud/tiinf/monitor/tilog"
	"go.uber.org/zap"

	globalngv1 "github.com/tidbcloud/tidb-management-service/api/spec/global/nextgen/v1"
	"github.com/tidbcloud/tidb-management-service/nextgen-global-service/domain/service/displayevent"
	"github.com/tidbcloud/tidb-management-service/utilities/bizerr"
)

func (s *serviceImpl) StopRestore(ctx context.Context, req *globalngv1.StopRestoreClusterRequest) bizerr.BizError {
	ctx, span := tracer.Start(ctx, "Domain.StopRestore")
	defer span.End()

	err := s.transaction.Transaction(ctx, func(ctx context.Context) error {
		return s.doStopRestore(ctx, req)
	})
	if err != nil {
		return bizerr.WrapError(err, "failed to stop restore")
	}
	return nil
}

func (s *serviceImpl) doStopRestore(
	ctx context.Context,
	req *globalngv1.StopRestoreClusterRequest,
) bizerr.BizError {
	clusterId, err := strconv.ParseUint(req.TargetClusterId, 10, 64)
	if err != nil {
		return bizerr.WrapError(err, "failed to parse target cluster id")
	}

	restore, berr := s.restoreRepo.Get(ctx, clusterId)
	if berr != nil {
		return berr.Chain("failed to get restore record")
	}
	if restore.State == "cancelled" {
		return nil
	}

	restore.State = "cancelled"
	berr = s.restoreRepo.Save(ctx, restore)
	if berr != nil {
		return berr.Chain("failed to update restore state to cancelled")
	}
	tilog.Info(ctx, "update restore state to cancelled", zap.String("cluster_id", req.TargetClusterId))

	restoreAdapter, berr := s.getRestoreAdapter(ctx, nil, restore)
	if berr != nil {
		return berr.Chain("failed to get restore adapter")
	}
	berr = restoreAdapter.StopRestore(ctx, req)
	if berr != nil {
		return berr.Chain("failed to stop restore")
	}
	displayEv := newRestoreDisplayEvent(ctx, restore, eventdata.EventStatusCanceled, "Restore canceled.")
	displayevent.Write(ctx, s.eventCommitter, displayEv)

	tilog.Info(ctx, "stop restore success", zap.Any("restore", restore))
	return nil
}
