package impl

import (
	"context"
	"testing"

	"github.com/stretchr/testify/mock"
	"github.com/stretchr/testify/require"
	"github.com/tidbcloud/dataflow-service/app/internal/status_matrix"
	backup_model_mock "github.com/tidbcloud/dataflow-service/app/models/backup/mock"
	"github.com/tidbcloud/dataflow-service/app/models/domain"
	"github.com/tidbcloud/dataflow-service/app/repo/entity"
	repo_mock "github.com/tidbcloud/dataflow-service/app/repo/mock"
)

func TestRestartOrCancelRestartPitBackupWhenNeed_RevertToActiveLogRegions(t *testing.T) {
	const clusterID uint64 = 1011

	pitBackupSwitcher := backup_model_mock.NewPitBackupSwitcher(t)
	logBackupRepo := repo_mock.NewLogBackupRepo(t)
	modifier := &regionModifierImpl{
		logBackupRepo:     logBackupRepo,
		pitBackupSwitcher: pitBackupSwitcher,
	}
	setting := &entity.BackupSetting{
		ClusterID: entity.ID(clusterID),
		PiTR:      &entity.PiTRSetting{Enable: true},
		Bucket: &entity.BucketSetting{
			DualRegionEnable: false,
			Buckets: []entity.BackupSettingBucket{
				{Regions: []string{"us-west-2"}, Master: true},
			},
		},
	}
	switchState := &entity.PitBackupSwitch{
		Status: entity.PitBackupStatusWaitingForRestarting,
		Action: entity.PitBackupSwitchAction{},
	}
	activeLogBackup := entity.LogBackup{
		Status: entity.LogBackupStatusRunning,
		BucketSettingSnapshot: &entity.BucketSetting{
			Buckets: []entity.BackupSettingBucket{
				{Regions: []string{"us-west-2"}, Master: true},
			},
		},
	}

	pitBackupSwitcher.On("GetOrCreatePitBackupSwitch", mock.Anything,
		mock.MatchedBy(func(req *domain.SwitchPitBackupReq) bool {
			return req.ClusterID == clusterID
		})).Return(&domain.GetOrCreatePitBackupSwitchResp{PitBackupSwitch: switchState}, nil).Once()
	logBackupRepo.On("List", mock.Anything, mock.Anything).
		Return([]entity.LogBackup{activeLogBackup}, nil).Once()
	pitBackupSwitcher.On("CancelRestart", mock.Anything,
		mock.MatchedBy(func(req *domain.CancelRestartPitBackupReq) bool {
			return req.ClusterID == clusterID
		})).Return(nil).Once()

	err := modifier.restartOrCancelRestartPitBackupWhenNeed(context.Background(), setting)

	require.NoError(t, err)
	pitBackupSwitcher.AssertNotCalled(t, "Restart", mock.Anything, mock.Anything)
}

func TestBackupSettingRegionFinalStep_ReturnsToNormal(t *testing.T) {
	matrix := NewBackupSettingStatusMatrix()
	next := matrix.CalculateNextStatusIfActionDone(status_matrix.CurrentStatus{
		Status:  string(entity.BackupSettingStatusEditingRegion),
		Actions: []string{string(entity.BackupSettingActionModifyRegion)},
	}, string(entity.BackupSettingActionModifyRegion))

	require.NotNil(t, next)
	require.Equal(t, string(entity.BackupSettingStatusNormal), next.Status)
	require.Empty(t, next.Actions)
}
