package br_svc

import (
	"context"
	"testing"
	"time"

	"github.com/stretchr/testify/require"
	"github.com/tidbcloud/pkgv2/bizerr"
	"github.com/tidbcloud/serverless-service/idl/pbgen/proto/console"
	"github.com/tidbcloud/serverless-service/internal/domain/constant"
	"github.com/tidbcloud/serverless-service/internal/domain/service/mock_service"
	"github.com/tidbcloud/serverless-service/internal/domain/vo"
	"go.uber.org/mock/gomock"
)

func TestListBackupsPassesOrgIDToDomainService(t *testing.T) {
	ctrl := gomock.NewController(t)
	br := mock_service.NewMockBackupRestoreService(ctrl)
	svc := &backupRestoreConsoleService{br: br}

	br.EXPECT().
		ListBackups(gomock.Any(), gomock.Any()).
		DoAndReturn(func(_ context.Context, opt *vo.ListUserBackupsOpt) ([]*vo.Backup, uint32, bizerr.BizError) {
			require.Equal(t, "1001", opt.TenantId)
			require.Equal(t, "2002", opt.ClusterId)
			return []*vo.Backup{}, 0, nil
		})

	_, err := svc.ListBackups(context.Background(), &console.ListBackupsRequest{
		OrgId:     "1001",
		ClusterId: "2002",
	})

	require.NoError(t, err)
}

func TestGetBackupPassesOrgIDToDomainService(t *testing.T) {
	ctrl := gomock.NewController(t)
	br := mock_service.NewMockBackupRestoreService(ctrl)
	svc := &backupRestoreConsoleService{br: br}
	now := time.Now()
	backup := &vo.Backup{
		ID:         "backup-id",
		BackupTime: &now,
		ExpireTime: &now,
	}

	br.EXPECT().
		GetBackup(gomock.Any(), "1001", "2002", "backup-id").
		Return(backup, nil)

	_, err := svc.GetBackup(context.Background(), &console.GetBackupRequest{
		OrgId:     "1001",
		ClusterId: "2002",
		BackupId:  "backup-id",
	})

	require.NoError(t, err)
}

func TestBuildRestoreCopiesOrgID(t *testing.T) {
	restore, err := buildRestore(&console.RestoreRequest{
		OrgId:     "1001",
		ProjectId: "3003",
		Source: &console.RestoreRequest_BackupId{
			BackupId: "backup-id",
		},
		Type: console.RestoreType_INPLACE,
	})

	require.NoError(t, err)
	require.Equal(t, "1001", restore.TenantId)
}

func TestGetBackupRetentionPassesOrgIDToDomainService(t *testing.T) {
	ctrl := gomock.NewController(t)
	br := mock_service.NewMockBackupRestoreService(ctrl)
	svc := &backupRestoreConsoleService{br: br}

	br.EXPECT().
		GetBackupRetention(gomock.Any(), "1001", "2002").
		Return(72*time.Hour, nil)

	resp, err := svc.GetBackupRetention(context.Background(), &console.GetBackupRetentionReq{
		OrgId:     "1001",
		ClusterId: "2002",
	})

	require.NoError(t, err)
	require.Equal(t, int32(72), resp.RetentionHours)
}

func TestGetRestoreProgressPassesOrgIDToDomainService(t *testing.T) {
	ctrl := gomock.NewController(t)
	br := mock_service.NewMockBackupRestoreService(ctrl)
	svc := &backupRestoreConsoleService{br: br}

	br.EXPECT().
		ListRestores(gomock.Any(), gomock.Any()).
		DoAndReturn(func(_ context.Context, opt *vo.ListRestoresOpt) ([]*vo.RestoreJob, uint32, bizerr.BizError) {
			require.Equal(t, "1001", opt.TenantId)
			require.Equal(t, "2002", opt.ClusterId)
			return []*vo.RestoreJob{{State: constant.RestoreJobStateRunning}}, 1, nil
		})

	_, err := svc.GetRestoreProgress(context.Background(), &console.GetRestoreProgressRequest{
		OrgId:     "1001",
		ClusterId: "2002",
	})

	require.NoError(t, err)
}
