package br

import (
	"context"
	"fmt"
	"testing"

	"github.com/stretchr/testify/mock"
	"github.com/stretchr/testify/require"
	"github.com/tidbcloud/cluster-service-ng/domain/entity"
	"github.com/tidbcloud/cluster-service-ng/domain/workflow"
	"github.com/tidbcloud/cluster-service-ng/pkg/runtime/actions"
	"github.com/tidbcloud/cluster-service-ng/pkg/storage/mysql/schema"
	repomocks "github.com/tidbcloud/cluster-service-ng/pkg/storage/repo/mocks"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
)

func TestSkipManualBackupActionForMissingSharedPoolMarksFailed(t *testing.T) {
	manualBackupRepo := repomocks.NewManualBackupRepo(t)
	manualBackup := &entity.ManualBackup{
		ManualBackup: schema.ManualBackup{
			BackupID:     "backup-1",
			ClusterID:    "cluster-1",
			SharedPoolID: "sp-1",
			Status:       schema.ManualBackupStatusRunning,
		},
	}

	manualBackupRepo.EXPECT().
		SetStatus(mock.Anything, "cluster-1", "backup-1", schema.ManualBackupStatusFailed).
		Return(nil).
		Once()

	skip, err := skipManualBackupActionForMissingSharedPool(
		context.Background(),
		manualBackupRepo,
		manualBackup,
		fmt.Errorf("failed to get manual backup action context infos: %w", &skipManualBackupActionError{
			cause: status.Error(codes.NotFound, "shared pool not found"),
		}),
		"test-action",
	)

	require.True(t, skip)
	require.NoError(t, err)
}

func TestMarkManualBackupSucceededActionSkipWhenBackupAlreadyFailed(t *testing.T) {
	manualBackupRepo := repomocks.NewManualBackupRepo(t)
	action := NewMarkManualBackupSucceededAction(manualBackupRepo)

	manualBackupRepo.EXPECT().
		Load(mock.Anything, "cluster-1", "backup-1", false).
		Return(&entity.ManualBackup{
			ManualBackup: schema.ManualBackup{
				BackupID:  "backup-1",
				ClusterID: "cluster-1",
				Status:    schema.ManualBackupStatusFailed,
			},
		}, nil).
		Once()

	err := action.Invoke(actions.ActionArgs{
		workflow.ManualBackupIdKey: actions.ActionArgString("backup-1"),
		workflow.TiDBClusterIdKey:  actions.ActionArgString("cluster-1"),
	})
	require.NoError(t, err)
}
