package action

import (
	"testing"

	"github.com/stretchr/testify/mock"
	"github.com/stretchr/testify/require"
	apiv1 "github.com/tidbcloud/cluster-service-ng/api/cluster-service-ng/v1beta"
	"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"
	repomocks "github.com/tidbcloud/cluster-service-ng/pkg/storage/repo/mocks"
)

func TestPreCreateTiDBClusterActionWaitsForResume(t *testing.T) {
	repo := repomocks.NewSharedPoolRepo(t)
	repo.EXPECT().Load(mock.Anything, "pool-1", false).Return(&entity.SharedPool{SharedPool: apiv1.SharedPool{
		Id: "pool-1", Phase: apiv1.SharedPool_RESUMING,
	}, PauseResumeState: entity.PauseResumeStateResuming}, nil)

	err := NewPreCreateTiDBClusterAction(repo).Invoke(actions.ActionArgs{
		workflow.SharedPoolIdKey: actions.ActionArgString("pool-1"),
	})

	require.ErrorContains(t, err, "waiting for resume")
}

func TestPreCreateTiDBClusterActionStopsOnDelete(t *testing.T) {
	repo := repomocks.NewSharedPoolRepo(t)
	repo.EXPECT().Load(mock.Anything, "pool-1", false).Return(&entity.SharedPool{SharedPool: apiv1.SharedPool{
		Id: "pool-1", Phase: apiv1.SharedPool_DELETING,
	}, PauseResumeState: entity.PauseResumeStateResuming}, nil)

	err := NewPreCreateTiDBClusterAction(repo).Invoke(actions.ActionArgs{
		workflow.SharedPoolIdKey: actions.ActionArgString("pool-1"),
	})

	require.ErrorContains(t, err, "deleting")
	require.True(t, actions.IsTerminalError(err))
}

func TestPreCreateTiDBClusterActionContinuesAfterResume(t *testing.T) {
	repo := repomocks.NewSharedPoolRepo(t)
	repo.EXPECT().Load(mock.Anything, "pool-1", false).Return(&entity.SharedPool{SharedPool: apiv1.SharedPool{
		Id: "pool-1", Phase: apiv1.SharedPool_AVAILABLE,
	}}, nil)

	err := NewPreCreateTiDBClusterAction(repo).Invoke(actions.ActionArgs{
		workflow.SharedPoolIdKey: actions.ActionArgString("pool-1"),
	})

	require.NoError(t, err)
}
