package common

import (
	"fmt"

	l4g "github.com/alecthomas/log4go"
	"github.com/dailymotion/allure-go"
	"github.com/stretchr/testify/assert"
)

const (
	warehouses           = 2
	districtPerWarehouse = 2
	customerPerDistrict  = 50
	timeFormat           = "2006-01-02 15:04:05"
	modifyCount          = 2
)

func CreateSession(t assert.TestingT, clusterId string) string {
	// init config
	dbassRequestInfo = GetDbassRequestInfo(t)
	orgId := dbassRequestInfo.CommonEnv.OrgId
	projectId := dbassRequestInfo.CommonEnv.ProjectId
	pathParam := map[string]string{"org_id": orgId, "project_id": projectId, "cluster_id": clusterId}

	// create a sql session
	sessionId := ""
	body := map[string]string{"database": ""}
	createSqlSessionResp := dbassRequestInfo.DbassRequest(t, "createSqlSession", body, pathParam, nil, nil)
	l4g.Info("create a sql session, path param is %s, body is %s, status code is %d", pathParam, body, createSqlSessionResp.Raw().StatusCode)
	l4g.Info("create a sql session response is %s", createSqlSessionResp.JSON())
	allure.Step(
		allure.Story("CreateSession"),
		allure.Description(fmt.Sprintf("create a sql session, path param is %s, body is"+
			" %s, status code is %d, sessioniD is :%s",
			pathParam,
			body,
			createSqlSessionResp.Raw().StatusCode,
			createSqlSessionResp.JSON().Path("$.data").String().Raw(),
		)),
		allure.Action(func() {
			createSqlSessionResp.Status(StatusOK)
			sessionId = createSqlSessionResp.JSON().Path("$.data").String().Raw()
			assert.NotEqual(t, "", sessionId)
		}))

	l4g.Info("new session id is %s", sessionId)
	return sessionId
}

func CloseSession(t assert.TestingT, clusterId, sessionId string) {
	// init config
	dbassRequestInfo = GetDbassRequestInfo(t)
	orgId := dbassRequestInfo.CommonEnv.OrgId
	projectId := dbassRequestInfo.CommonEnv.ProjectId
	pathParam := map[string]string{"org_id": orgId, "project_id": projectId, "cluster_id": clusterId, "session_id": sessionId}

	// create a sql session
	delSqlSessionResp := dbassRequestInfo.DbassRequest(t, "delSqlSession", nil, pathParam, nil, nil)
	l4g.Info("delete sql session %s, path param is %s, status code is %d", sessionId, pathParam, delSqlSessionResp.Raw().StatusCode)
	allure.Step(
		allure.Story("CloseSession"),
		allure.Description(fmt.Sprintf("delete sql session %s, path param is %s, status code is %d", sessionId, pathParam, delSqlSessionResp.Raw().StatusCode)),
		allure.Action(func() {
			delSqlSessionResp.Status(StatusOK)
		}))
}

func CheckSessionIsClosed(t assert.TestingT, clusterId, sessionId string) {
	// init config
	dbassRequestInfo = GetDbassRequestInfo(t)
	orgId := dbassRequestInfo.CommonEnv.OrgId
	projectId := dbassRequestInfo.CommonEnv.ProjectId
	pathParam := map[string]string{"org_id": orgId, "project_id": projectId, "cluster_id": clusterId}

	// check session has been closed
	dbName := "sessionDeleted"
	sql := fmt.Sprintf("create database %s;", dbName)
	body := map[string]string{"sql": sql, "sessionid": sessionId}
	runSqlResp := dbassRequestInfo.DbassRequest(t, "executeSql", body, pathParam, nil, nil)

	allure.Step(
		allure.Story("CheckSessionIsClosed"),
		allure.Description(fmt.Sprintf("run sql, path param is %s, body is"+
			" %s, http status code is %d. Actual message is : %v",
			pathParam,
			body,
			runSqlResp.Raw().StatusCode,
			runSqlResp.JSON().Path("$.message").String().Raw(),
		)),
		allure.Action(func() {
			runSqlResp.JSON().Object().ValueEqual("code", 60100001)
			runSqlResp.JSON().Path("$.message").String().Contains("your session has expired")
		}))
}
