package imp

import (
	"fmt"
	"github.com/tidbcloud/qa-PlatformAPIAuto/models"
	"testing"

	"github.com/dailymotion/allure-go"
	"github.com/tidbcloud/qa-PlatformAPIAuto/common"
	"github.com/tidbcloud/qa-PlatformAPIAuto/webScene/pkg/cluster"
	imppkg "github.com/tidbcloud/qa-PlatformAPIAuto/webScene/pkg/import"
)

type BaseImportScene struct {
	cluster.Cluster
	imppkg.Import

	T *testing.T

	ImportData       *models.ClusterIdImportsBody
	SearchImportFile *models.ImportsSearchimportfilesBody
	PrecheckData     *models.ImportsValidateBody

	Provider string
}

func (b *BaseImportScene) Init(t *testing.T, clusterId, provider string, isServerless bool) {
	b.T = t
	b.Provider = provider
	requestInfo := common.GetDbassRequestInfo(t)
	if isServerless {
		b.Cluster = &cluster.ServerlessCluster{
			T:                t,
			DbassRequestInfo: requestInfo,
		}
	} else {
		b.Cluster = &cluster.DedicatedCluster{
			T:                t,
			DbassRequestInfo: requestInfo,
		}
	}

	if provider == AwsProvider {
		b.Import = imppkg.NewS3Import(t, requestInfo)
	} else if provider == GcpProvider {
		b.Import = imppkg.NewGsImport(t, requestInfo)
	}

	if clusterId != "" {
		b.Cluster.SetId(clusterId)
	}
}

func (b *BaseImportScene) CreateClusterStep() {
	allure.Step(
		allure.Description("1. create cluster, 2. update password, 3. add traffic"),
		allure.Action(func() {
			b.Cluster.Create(b.Provider)
		}),
	)
}

func (b *BaseImportScene) ImportPreViewStep() {
	allure.Step(
		allure.Description("preview import job"),
		allure.Action(func() {
			b.Import.PreView()
		}),
	)
}

func (b *BaseImportScene) ImportArnName() string {
	return fmt.Sprintf("arn:aws:iam::676546228356:role/scene-test-import-cluster%s-role", b.Cluster.Id())
}

func (b *BaseImportScene) ImportPreCheckStep() {
	allure.Step(
		allure.Description("pre check import job"),
		allure.Action(func() {
			b.Import.PreCheck()
		}),
	)
}

func (b *BaseImportScene) CreateImportStep() {
	allure.Step(
		allure.Description("create import till importing"),
		allure.Action(func() {
			b.Import.Create()
			b.waitImporting()
		}),
	)
}

func (b *BaseImportScene) CreateImportTillCompletedStep() {
	allure.Step(
		allure.Description("create import: importing -> completed"),
		allure.Action(func() {
			b.Import.Create()
			b.waitCompleted()
			b.checkFileSize()
		}),
	)
}

// CancelImport need not to check the `canceling` status
// so we do not need `CancelImportTillCancelingStep` temporarily
func (b *BaseImportScene) CancelImportStep() {
	allure.Step(
		allure.Description("cancel import: importing -> canceling -> canceled"),
		allure.Action(func() {
			b.Import.Cancel()
			b.waitCanceled()
		}),
	)
}

func (b *BaseImportScene) CreateImportCredentialStep() {
	allure.Step(
		allure.Description("create import credential"),
		allure.Action(func() {
			dataIngestionProfile := b.Cluster.GetDataIngestionProfile()
			err := b.Import.CreateCredential(dataIngestionProfile)
			if err != nil {
				allure.FailNow(err)
			}
		}),
	)
}

func (b *BaseImportScene) DeleteImportCredentialStep() {
	allure.Step(
		allure.Description("delete import credential"),
		allure.Action(func() {
			b.Import.DeleteCredential()
		}),
	)
}

func (c *BaseImportScene) BuildDataStep(data *models.ClusterIdImportsBody) {
	allure.Step(
		allure.Description(fmt.Sprintf("build import data: %v", data)),
		allure.Action(func() {
			c.SetImportData(data)
		}),
	)
}

func (c *BaseImportScene) GetTargetTableStep() {
	allure.Step(
		allure.Description("get target table"),
		allure.Action(func() {
			c.Import.GetTargetTable()
		}),
	)
}

func (c *BaseImportScene) SearchImportFileStep() {
	allure.Step(
		allure.Description("search import file"),
		allure.Action(func() {
			c.Import.SearchImportFiles()
		}),
	)
}
