package server

import (
	"context"
	"fmt"

	apiv1 "github.com/tidbcloud/cluster-service-ng/api/cluster-service-ng/v1beta"
	"github.com/tidbcloud/cluster-service-ng/domain/server/br"
	"github.com/tidbcloud/cluster-service-ng/pkg/storage/mysql/schema"
	"github.com/tidbcloud/tiinf/monitor/tilog"
	"go.uber.org/zap"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
)

var ErrLightweightRestoreNotFound = fmt.Errorf("restore not found")

func (s *serverImpl) GetLightweightRestore(ctx context.Context, req *br.GetLightweightRestoreInput) (*br.GetLightweightRestoreOutput, error) {
	restore, err := s.lwRestoreRepo.Load(ctx, req.RestoreId, true)
	if err != nil {
		if status.Code(err) == codes.NotFound {
			return nil, ErrLightweightRestoreNotFound
		}
		tilog.Error(ctx, "failed to load lw restore record", zap.Error(err), zap.String("restoreId", req.RestoreId))
		return nil, fmt.Errorf("failed to load lw restore record: %w", err)
	}
	if restore.DeletedAt.Valid {
		return &br.GetLightweightRestoreOutput{Status: apiv1.LightweightRestoreStatus_DELETED}, nil
	}

	restoreAdaptor := br.GetLightweightRestoreAdaptor(restore, s.clustergatewayCli, s.sharedPoolRepo)

	switch restore.Status {
	case schema.LightweightRestoreStatusRunning:
		return restoreAdaptor.GetRestoreInRunning(ctx, restore)
	case schema.LightweightRestoreStatusSucceeded:
		return &br.GetLightweightRestoreOutput{Status: apiv1.LightweightRestoreStatus_SUCCEED}, nil
	case schema.LightweightRestoreStatusFailed:
		return &br.GetLightweightRestoreOutput{
			Status:  apiv1.LightweightRestoreStatus_FAILED,
			Failure: restoreFailureOutput(restore.FailureSource, restore.FailureCode, restore.FailureMessage),
		}, nil
	case schema.LightweightRestoreStatusCancelled:
		return &br.GetLightweightRestoreOutput{Status: apiv1.LightweightRestoreStatus_DELETING}, nil
	}

	return &br.GetLightweightRestoreOutput{Status: apiv1.LightweightRestoreStatus_LIGHTWEIGHT_RESTORE_STATUS_UNSPECIFIED}, nil
}
