package webScene

import (
	"strconv"
	"testing"
	"time"

	l4g "github.com/alecthomas/log4go"
	"github.com/stretchr/testify/assert"
	"github.com/tidbcloud/qa-PlatformAPIAuto/util"
	"github.com/tidbcloud/qa-gourd/ProductModel"
	"github.com/tidbcloud/qa-gourd/handler"

	"github.com/dailymotion/allure-go"
	"github.com/tidbcloud/qa-PlatformAPIAuto/common"
	iamCases "github.com/tidbcloud/qa-PlatformAPIAuto/webScene/cbp/iam"
	platformCases "github.com/tidbcloud/qa-PlatformAPIAuto/webScene/cbp/platform"
)

/*
 check sql editor on serverless tier
*/

func (w *WebE2ECase) ServerlessTierCreateCluster(t *testing.T) {
	w.Reporter.T = t
	w.Reporter.SceneReport(func() {
		if w.WebRequestInfo.Cluster.ClusterId == "" {
			w.Reporter.StepReport("create cluster",
				func() {
					_, err := w.WebRequestInfo.CreateServerlessCluster()
					if err != nil {
						assert.FailNow(w.Reporter.T, err.Error())
					}
				})
		}
	})
}

func (w *WebE2ECase) ServerlessTierSpendLimit(t *testing.T) {
	w.Reporter.T = t
	w.Reporter.SceneReport(func() {
		w.CheckUpdateSpendLimit()
	})
}

func (w *WebE2ECase) ServerlessTierConnectOperation(t *testing.T) {
	w.Reporter.T = t
	w.Reporter.SceneReport(func() {
		w.CheckFilterAndConnectOperation()
	})
}

// TODO: need use new arch
func (w *WebE2ECase) ServerlessTierBackupAndRestore(t *testing.T) {
	//t.Run("CheckFilterAndConnectOperation", func(t *testing.T) {
	allure.Test(t,
		allure.Epic("TestServerlessBackupAndRestore"),
		allure.Feature("ServerlessBackupAndRestore"),
		allure.Description("ServerlessBackupAndRestore"),
		allure.Action(func() {
			common.ServerlessBackupAndRestore(t, "", w.WebRequestInfo.Cluster.ClusterId)
		}))
	//})
}

func (w *WebE2ECase) ServerlessTierUpdatePassword(t *testing.T) {
	w.Reporter.T = t
	w.Reporter.SceneReport(func() {
		w.CheckUpdatePassword()
	})
}

func (w *WebE2ECase) ServerlessTierSQLUser(t *testing.T) {
	w.SetReporter(t)
	w.Reporter.SceneReport(func() {
		iamCases.RunSQLUserTest(w.WebRequestInfo, w.URLInfoMap, &w.Reporter)
	})
}

func (w *WebE2ECase) ServerlessTierDataAPP(t *testing.T) {
	w.SetReporter(t)
	w.Reporter.SceneReport(func() {
		platformCases.RunAllDataAPPSceneTest(w.WebRequestInfo, w.URLInfoMap, &w.Reporter)
	})
}
func (w *WebE2ECase) ServerlessTierChat2QueryBasicCheck(t *testing.T) {
	w.SetReporter(t)
	w.Reporter.SceneReport(func() {
		platformCases.RunChat2QueryBasicCheckSceneTest(w.WebRequestInfo, w.URLInfoMap, &w.Reporter)
	})
}

/*
*
check generous dml and ddl
*/
func (w *WebE2ECase) ServerlessTierRunSqlByChat2Query(t *testing.T) {
	w.SetReporter(t)
	w.Reporter.SceneReport(func() {
		platformCases.RunChat2QuerySQLCheckSceneTest(w.WebRequestInfo, w.URLInfoMap, &w.Reporter)
	})
}

func (w *WebE2ECase) ServerlessTierShadowAccount(t *testing.T) {
	w.SetReporter(t)
	if handler.EnvFile == ProductModel.Prod {
		w.Reporter.StepReport("ServerlessTierShadowAccount - CanNotRunInProd",
			func() {
				assert.True(w.Reporter.T, false)
			})
		return
	}
	w.Reporter.SceneReport(func() {
		iamCases.RunShadowAccountSceneTest(w.WebRequestInfo, w.URLInfoMap, &w.Reporter)
	})
}

/*func DevTierAutoBackupOperation(t *testing.T) {
	common.SetTimeZone(t)
	var provider = "aws"
	if devTierClusterId == "" {
		//common.DeleteDevTierCluster(t)
		//t.Run("CheckCreateCluster", func(t *testing.T){
			allure.Test(t,
				allure.Epic("TestDevTierAutoBackupOperation"),
				allure.Feature("CheckCreateCluster"),
				allure.Description("CheckCreateCluster"),
				allure.Action(func() {
					devTierClusterId = common.CheckCreateCluster(t, provider, true, tidbCount, devTikvCount, devTiflashCount, "", "", "")
				}))
		//})
	}

	//t.Run("CheckAutoBackupOperation", func(t *testing.T) {
	allure.Test(t,
		allure.Epic("TestDevTierAutoBackupOperation"),
		allure.Feature("CheckAutoBackupOperation"),
		allure.Description("CheckAutoBackupOperation"),
		allure.Action(func() {
			common.CheckAutoBackupOperation(t, "", devTierClusterId, true)
		}))
	//})
}*/

func (w *WebE2ECase) ServerlessTierWorkloadRunOperation(t *testing.T) {
	w.Reporter.T = t
	w.Reporter.SceneReport(func() {
		w.WebRequestInfo.RunChBenchmarkWorkload(10 * time.Minute)
	})
}

func (w *WebE2ECase) ServerlessTierMonitoring(t *testing.T) {
	var provider = "aws"
	var sessionList [10]string
	// wait sample data ready
	time.Sleep(time.Minute)

	sessionId := ""
	// produce some db data
	if !util.ContainsString(w.CaseList, "ServerlessTierWorkloadRunOperation") {
		allure.Test(t,
			allure.Epic("TestServerlessTierMonitoring"),
			allure.Feature("PrepareDBData"),
			allure.Description("CreateSession"),
			allure.Action(func() {
				sessionId = common.CreateSession(t, w.WebRequestInfo.Cluster.ClusterId)
			}))
		if sessionId == "" {
			return
		}

		allure.Test(t,
			allure.Epic("TestServerlessTierMonitoring"),
			allure.Feature("PrepareDBData"),
			allure.Description("PrepareDBData"),
			allure.Action(func() {
				common.PrepareDBData(t, w.WebRequestInfo.Cluster.ClusterId, sessionId)
			}))
		// prepare sessions
		allure.Test(t,
			allure.Epic("TestServerlessTierMonitoring"),
			allure.Feature("PrepareQueryMetrics"),
			allure.Description("CreateSession"),
			allure.Action(func() {
				for i := 0; i < 10; i++ {
					sId := common.CreateSession(t, w.WebRequestInfo.Cluster.ClusterId)
					l4g.Info("create session success, id is: %s", sId)
					sessionList[i] = sId
					common.UseDBCheck(t, w.WebRequestInfo.Cluster.ClusterId, sessionList[i], "", 200)
				}
			}))

		// prepare metrics by sessions
		allure.Test(t,
			allure.Epic("TestServerlessTierMonitoring"),
			allure.Feature("PrepareQueryMetrics"),
			allure.Description("PrepareQueryMetrics"),
			allure.Action(func() {
				for round := 0; round < 10; round++ {
					for i := 0; i < 10; i++ {
						l4g.Info("try to query db, session id is: %s", sessionList[i])
						common.QueryTableCustomer(t, w.WebRequestInfo.Cluster.ClusterId, sessionList[i])
					}
				}
			}))
	}
	time.Sleep(time.Second * 60)
	//check monitoring

	metrics := common.GetMetricQuery("serverlessClusterMetrics.csv", true)
	expValue := float64(0)
	allure.Test(t,
		allure.Epic("TestServerlessTierMonitoring"),
		allure.Feature("CheckMonitoring"),
		allure.Description("CheckMonitoring: "),
		allure.Action(func() {
			for _, m := range metrics {
				switch m.Key {
				case "TC":
					expValue = 10
				default:
					expValue, _ = strconv.ParseFloat(m.Value, 64)
				}
				allure.Step(
					allure.Story("CheckMonitoring"),
					allure.Description("Query "+m.Desc),
					allure.Action(func() {
						common.CheckServerlessMonitoringMetric(t, w.WebRequestInfo.Env, provider, w.WebRequestInfo.Cluster.Region, w.WebRequestInfo.Cluster.ClusterId, 15*60, m, expValue)
					}))
			}
		}))
	// check cluster statement
	//allure.Test(t,
	//	allure.Epic("TestServerlessStatements"),
	//	allure.Feature("CheckServerlessStatements"),
	//	allure.Description("CheckServerlessStatements"),
	//	allure.Action(func() {
	//		common.CheckServerlessStatement(t, serverlessTierClusterId, sessionId)
	//	}))

	if sessionId != "" {
		//delete session
		allure.Test(t,
			allure.Epic("TestServerlessTierMonitoring"),
			allure.Feature("CloseSession"),
			allure.Description("CloseSession"),
			allure.Action(func() {
				common.CloseSession(t, w.WebRequestInfo.Cluster.ClusterId, sessionId)
				for _, sid := range sessionList {
					common.CloseSession(t, w.WebRequestInfo.Cluster.ClusterId, sid)
				}
			}))
	}

	//time.Sleep(time.Minute * 30)
}

func (w *WebE2ECase) ServerlessTierSlowQuery(t *testing.T) {
	sessionId := ""

	allure.Test(t,
		allure.Epic("TestServerlessSlowQuery"),
		allure.Feature("PrepareDBData"),
		allure.Description("CreateSession"),
		allure.Action(func() {
			sessionId = common.CreateSession(t, w.WebRequestInfo.Cluster.ClusterId)
		}))
	if sessionId == "" {
		return
	}

	// check SlowQuery
	allure.Test(t,
		allure.Epic("TestServerlessSlowQuery"),
		allure.Feature("CheckSlowQuery"),
		allure.Description("CheckSlowQuery"),
		allure.Action(func() {
			common.CheckServerlessSlowQuery(t, w.WebRequestInfo.Cluster.ClusterId, sessionId)
		}))

	allure.Test(t,
		allure.Epic("TestServerlessSlowQuery"),
		allure.Feature("CloseSession"),
		allure.Description("CloseSession"),
		allure.Action(func() {
			common.CloseSession(t, w.WebRequestInfo.Cluster.ClusterId, sessionId)
		}))

}

func (w *WebE2ECase) ServerlessTierSQLStatement(t *testing.T) {
	w.Reporter.T = t
	w.Reporter.SceneReport(func() {
		w.Reporter.StepReport("TestServerlessSQLStatement",
			func() {
				w.CheckClusterStatement()
			})
	})
}

func (w *WebE2ECase) ServerlessTierEvents(t *testing.T) {
	w.Reporter.T = t
	w.Reporter.SceneReport(func() {
		w.Reporter.StepReport("TestServerlessEvents",
			func() {
				w.CheckEvents(24 * 60 * 60)
			})
	})
}

func (w *WebE2ECase) ServerlessTierPrivateLink(t *testing.T) {
	w.Reporter.T = t
	w.Reporter.SceneReport(func() {
		w.CheckServerlessPrivateLinkConnect()
	})
}
