package MainOrder

import (
	"flag"
	"strings"
	"testing"
	"time"

	"github.com/tidbcloud/qa-PlatformAPIAuto/openAPIScene"
	"github.com/tidbcloud/qa-PlatformAPIAuto/webScene"

	l4g "github.com/alecthomas/log4go"
	"github.com/tidbcloud/qa-PlatformAPIAuto/common"
	"github.com/tidbcloud/qa-gourd/ProductModel"
	"github.com/tidbcloud/qa-gourd/ProductService"
	"github.com/tidbcloud/qa-gourd/handler"
)

var (
	IsOpenAPI         string
	DoSceneBillsCheck string
	CaseList          string

	DedicatedList          []string
	ServerlessTierCaseList []string
	ParallelCaseList       []string
)

var RequestInfo ProductService.E2ECase
var orgType string
var clusterChan []*ProductService.Cluster

func CommandHandler() {
	flag.StringVar(&IsOpenAPI, "IsOpenAPI", "N", "")
	flag.StringVar(&CaseList, "CaseList", "", "CaseList")
	flag.StringVar(&common.InfraImage, "InfraImage", "", "infra image")
	flag.StringVar(&common.FeatureGates, "FeatureGates", "", "FeatureGates(json string)")
	flag.StringVar(&common.ExpFeatureGates, "ExpFeatureGates", "", "ExpFeatureGates(json string)")
	flag.StringVar(&common.RequireSecureTransport, "RequireSecureTransport", "off", "RequireSecureTransport")
	flag.StringVar(&common.S3AccessKey, "S3AccessKey", "", "S3AccessKey")
	flag.StringVar(&common.S3SecretKey, "S3SecretKey", "", "S3SecretKey")
	flag.StringVar(&DoSceneBillsCheck, "DoSceneBillsCheck", "N", "DoSceneBillsCheck")

}

func Context() {
	orgType = ProductModel.Specify
	if IsOpenAPI == "N" {
		webRequestInfo := ProductService.GetWebAPIRequestInfo(&testing.T{}, orgType)
		if handler.ClusterId != "" {
			err := webRequestInfo.ReloadClusterContext(handler.ClusterId)
			if err != nil {
				panic(err.Error())
			}
			webRequestInfo.UpdatePassword(handler.ClusterInfo.Password)
			webRequestInfo.Cluster.RemainFlag = true
		}
		RequestInfo = &webScene.WebE2ECase{
			WebRequestInfo: webRequestInfo,
		}
	} else {
		openAPIRequestInfo := ProductService.GetOpenAPIRequestInfo(&testing.T{}, orgType)
		if handler.ClusterId != "" {
			err := openAPIRequestInfo.ReloadClusterContext(handler.ClusterId)
			if err != nil {
				panic(err.Error())
			}
			openAPIRequestInfo.GetWebRequestInfo().UpdatePassword(handler.ClusterInfo.Password)
			openAPIRequestInfo.Cluster.Password = handler.ClusterInfo.Password
			openAPIRequestInfo.Cluster.RemainFlag = true
		}
		RequestInfo = &openAPIScene.OpenAPIE2ECase{
			OpenAPIRequestInfo: openAPIRequestInfo,
		}
	}
	RequestInfo.AnalyzeAPIInfo()
}

// cases route
func Analysis() {
	caseListData := strings.Split(CaseList, " ")
	RequestInfo.SetCaseList(caseListData)
	if handler.ClusterId != "" && !RequestInfo.GetClusterInfo().IsServerless {
		//已有dedicated 集群，全部路由dedicated_test，串行执行，不再新建集群
		DedicatedList = caseListData
		return
	}

	for _, casedata := range caseListData {
		if (strings.Contains(casedata, "Dedicated") || strings.Contains(casedata, "EKSInfraProvider") ||
			strings.Contains(casedata, "Old")) && !strings.Contains(casedata, "Import") {
			DedicatedList = append(DedicatedList, casedata)
			continue
		} else if strings.Contains(casedata, "Serverless") && !strings.Contains(casedata, "CDC") {
			ServerlessTierCaseList = append(ServerlessTierCaseList, casedata)
			continue
		} else {
			ParallelCaseList = append(ParallelCaseList, casedata)
			continue
		}
	}
	if DoSceneBillsCheck == "Y" {
		ProductService.DoBillsCheck = true
		ParallelCaseList = append(ParallelCaseList, "SceneBillsCheckBeta")
	}
}

func Setup() {
	CommandHandler()
	handler.APIAutoInitialization()
	Context()
	Analysis()
}

func TestMain(m *testing.M) {
	l4g.Info("start to handle command line , current time is : %s", time.Now().Format("2006-01-02 15:04:05"))
	l4g.LoadConfiguration("../conf/log.xml")
	l4g.Debug("log-emulator log4go is ready")
	defer l4g.Close()

	Setup()
	m.Run()
	Teardown()
}

func Teardown() {
	for _, cluster := range clusterChan {
		if !cluster.RemainFlag {
			RequestInfo.DeleteClusterById(cluster.ClusterId)
		}
	}
}

func DeepCopy(src ProductService.E2ECase) ProductService.E2ECase {
	switch v := src.(type) {
	case *webScene.WebE2ECase:
		return v.DeepCopy()
	case *openAPIScene.OpenAPIE2ECase:
		return v.DeepCopy()
	}
	return nil
}
