package dm

import (
	"fmt"

	"github.com/tidbcloud/dataflow-service-e2e/cases"
	"github.com/tidbcloud/dataflow-service-e2e/cases/essential/common"
	"github.com/tidbcloud/dataflow-service-e2e/internal/config"
	. "github.com/tidbcloud/dataflow-service-e2e/internal/model"
	"github.com/tidbcloud/dataflow-service-e2e/internal/tidbcloud/essential"
)

type DMPrecheckLifecycleCase struct {
	cases.BaseCase
	provider CloudProviderType
}

func NewDMPrecheckLifecycleCase(provider CloudProviderType) cases.E2ECase {
	return &DMPrecheckLifecycleCase{provider: provider}
}
func (c *DMPrecheckLifecycleCase) Name() string {
	return fmt.Sprintf("%sEssentialV1DMPrecheckLifecycleSmoke", c.provider)
}
func (c *DMPrecheckLifecycleCase) Tags() map[string]string {
	return map[string]string{cases.TagKeyDomain: config.DomainDM, cases.TagKeyAPIModes: common.APIModesBoth}
}
func (c *DMPrecheckLifecycleCase) DeclareDependencyRequirements() map[string]DependencyRequirement {
	region := config.GlobalConfig.DefaultRegionOf(c.provider)
	return map[string]DependencyRequirement{
		"essential": &TiDBServerlessRequirement{
			Dedicated: true,
			TiDBServerlessDimensions: TiDBServerlessDimensions{
				CloudProvider: c.provider,
				Region:        region,
				ServicePlan:   essential.ServicePlanEssential,
			},
		},
		"mysql": &MySQLRequirement{MySQLDimensions: MySQLDimensions{
			NetworkType: DataflowNetworkTypeNetworkTypePublic,
		}},
	}
}
func (c *DMPrecheckLifecycleCase) Run() {
	cluster, source := c.TiDBServerless("essential"), c.MySQL("mysql")
	client := essential.NewDMClient()
	spec := essential.NewMigrationSpec(c.Name(), source, "test1", "lifecycle_marker")
	c.Step("validate DM endpoints", func() error { return client.Prepare(c.Context(), cluster, source, "test1", "lifecycle_marker") })
	var id string
	defer func() {
		if id != "" {
			c.Step("cancel unfinished DM precheck", func() error {
				return client.CancelPrecheck(c.CleanupContext(), cluster, id)
			})
		}
	}()
	c.Step("create DM precheck", func() error { var err error; id, err = client.PrecheckSpec(c.Context(), cluster, spec); return err })
	expectPrecheckLifecycle(&c.BaseCase, client, cluster, id)
	// A successful terminal precheck is not a live resource and must not be
	// canceled during cleanup.
	id = ""
}
