package gcp

import (
	"fmt"
	"testing"
	"time"

	"github.com/dailymotion/allure-go"
	"github.com/tidbcloud/qa-PlatformAPIAuto/common"
	"github.com/tidbcloud/qa-PlatformAPIAuto/models"
	"github.com/tidbcloud/qa-PlatformAPIAuto/util"
	"github.com/tidbcloud/qa-PlatformAPIAuto/webScene/cdc"
	dpCommon "github.com/tidbcloud/qa-PlatformAPIAuto/webScene/common"
)

func ExecuteChangefeedRcu(t *testing.T) {
	test := &CdcChangefeedRcuSceneTest{
		cdc.CommonSceneTest{
			SceneTest: dpCommon.SceneTest{
				T:                t,
				DbaasRequestInfo: common.GetDbassRequestInfo(t),
				ClusterId:        GetClusterId(),
				TestSchemaName: fmt.Sprintf("%s_%s",
					dpCommon.SCHEMA_CHANGEFEED_RCU, util.FnvHash(common.Envn+string(dpCommon.CloudProviderTypeGCP)+common.GetDbassRequestInfo(t).CommonEnv.Email)),
			},
			StartUTC: time.Now().UTC(),
		},
	}
	test.Run()
}

type CdcChangefeedRcuSceneTest struct {
	cdc.CommonSceneTest
}

func (s *CdcChangefeedRcuSceneTest) Run() {
	allure.Test(s.T,
		allure.Epic(fmt.Sprintf("%s-%s", dpCommon.CloudProviderTypeGCP, dpCommon.ChangefeedRcu)),
		allure.Feature(string(dpCommon.ChangefeedRcu)),
		allure.Description(string(dpCommon.ChangefeedRcu)),
		allure.Action(func() {
			s.TestDownStreamConnectionStep(s.buildTestConnectToMySQLReq())
			s.ExecuteSQLToMySQLStep(s.InitMySQL)
			s.ExecuteTidbDataWithDefaultClusterIDStep(s.InitTidb)
			s.ExecuteTidbDataWithDefaultClusterIDStep(s.SetGC720h)
			s.DescribeTidbSchemaTableStep()
			s.CreateChangefeedStep(s.buildCreateTidbToMySQLChangefeedReq())
			s.WaitChangefeedStatusReadyStep(models.DataflowConnectorStatusRUNNING)
			s.ExecuteTidbDataWithDefaultClusterIDStep(s.SetGC10m)
			s.CheckChangefeedRcuInstanceTypeStep(dpCommon.RCU2)
			s.ExecuteTidbDataWithDefaultClusterIDStep(s.InitTidb)
			s.ExecuteTidbDataWithDefaultClusterIDStep(s.InsertToFullStageTable)
			s.ExecuteMySQLDataWithRetryStep(s.CheckFullStageTableCount)
			s.ScaleChangefeedStep(s.buildScaleChangefeedRcuReq(dpCommon.RCU4))
			s.WaitChangefeedStatusReadyStep(models.DataflowConnectorStatusRUNNING)
			s.CheckChangefeedRcuInstanceTypeStep(dpCommon.RCU4)
			s.ScaleChangefeedStep(s.buildScaleChangefeedRcuReq(dpCommon.RCU16))
			s.WaitChangefeedStatusReadyStep(models.DataflowConnectorStatusRUNNING)
			s.CheckChangefeedRcuInstanceTypeStep(dpCommon.RCU16)
			s.ScaleChangefeedStep(s.buildScaleChangefeedRcuReq(dpCommon.RCU8))
			s.WaitChangefeedStatusReadyStep(models.DataflowConnectorStatusRUNNING)
			s.CheckChangefeedRcuInstanceTypeStep(dpCommon.RCU8)
			s.ScaleChangefeedStep(s.buildScaleChangefeedRcuReq(dpCommon.RCU2))
			s.WaitChangefeedStatusReadyStep(models.DataflowConnectorStatusRUNNING)
			s.CheckChangefeedRcuInstanceTypeStep(dpCommon.RCU2)
			s.ExecuteTidbDataWithDefaultClusterIDStep(s.CreateIncreStageTable)
			s.ExecuteTidbDataWithDefaultClusterIDStep(s.InsertToIncreStageTable)
			s.ExecuteMySQLDataWithRetryStep(s.CheckTableIncreTestData)
			s.DeleteChangefeedStep()
		}))
}

func (s *CdcChangefeedRcuSceneTest) buildTestConnectToMySQLReq() *models.DataflowConnectorCreateReq {
	return &models.DataflowConnectorCreateReq{
		ConnectorType: models.DataflowConnectorTypeMYSQL.Pointer(),
		MysqlInfo: &models.DataflowMySQLInfo{
			Connection: &models.DataflowConnection{
				Endpoint: s.DbaasRequestInfo.CommonEnv.MysqlUrl,
				Username: s.DbaasRequestInfo.CommonEnv.MysqlUser,
				Password: s.DbaasRequestInfo.CommonEnv.MysqlPassword,
			},
		},
	}
}

func (s *CdcChangefeedRcuSceneTest) buildCreateTidbToMySQLChangefeedReq() *models.DataflowConnectorCreateReq {
	return &models.DataflowConnectorCreateReq{
		ChangefeedInstanceType: dpCommon.RCU2,
		ConnectorType:          models.DataflowConnectorTypeMYSQL.Pointer(),
		MysqlInfo: &models.DataflowMySQLInfo{
			Connection: &models.DataflowConnection{
				Endpoint: s.DbaasRequestInfo.CommonEnv.MysqlUrl,
				Username: s.DbaasRequestInfo.CommonEnv.MysqlUser,
				Password: s.DbaasRequestInfo.CommonEnv.MysqlPassword,
			},
			TableConfig: &models.DataflowTableConfig{
				FilterRule: []string{
					fmt.Sprintf("%s.test*", s.TestSchemaName),
					fmt.Sprintf("%s.incre_test*", s.TestSchemaName),
				},
				Mode: models.DataflowTableModeFORCESYNC.Pointer(),
			},
			StartPosition: &models.DataflowStartPosition{
				Mode: models.DataflowStartModeFROMUTC.Pointer(),
				Utc:  s.StartUTC.Format(time.RFC3339),
			},
		},
	}
}

func (s *CdcChangefeedRcuSceneTest) buildScaleChangefeedRcuReq(rcuInstanceType string) *models.DataflowConnectorScaleReq {
	return &models.DataflowConnectorScaleReq{
		ChangefeedIntanceType: rcuInstanceType,
	}
}
