package platform

import (
	"fmt"
	"net/http"

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

// CreateSession create a sql session
func (pt *PlatformTest) CreateSession(clusterId ...string) string {
	createSessionCluster := pt.w.Cluster.ClusterId
	if len(clusterId) != 0 {
		createSessionCluster = clusterId[0]
	}

	// create a sql session
	pathParam := map[string]string{
		"org_id":     pt.w.User.OrgId,
		"project_id": pt.w.User.ProjectId,
		"cluster_id": createSessionCluster,
	}

	// create a sql session
	sessionId := ""
	body := map[string]string{
		"database": "",
	}
	createSqlSessionResp := pt.w.DoWebAPIRequestByUrlInfo(pt.URLInfoMap["createSqlSession"], body, pathParam, nil)
	pt.Reporter.StepReport(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(),
	),
		func() {
			createSqlSessionResp.Status(http.StatusOK)
			sessionId = createSqlSessionResp.JSON().Path("$.data").String().Raw()
			assert.NotEqual(pt.Reporter.T, "", sessionId)
		})

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

func (pt *PlatformTest) CloseSession(sessionId string, clusterId ...string) {
	closeSessionCluster := pt.w.Cluster.ClusterId
	if len(clusterId) != 0 {
		closeSessionCluster = clusterId[0]
	}
	pathParam := map[string]string{
		"org_id":     pt.w.User.OrgId,
		"project_id": pt.w.User.ProjectId,
		"cluster_id": closeSessionCluster,
		"session_id": sessionId,
	}

	// create a sql session
	delSqlSessionResp := pt.w.DoWebAPIRequestByUrlInfo(pt.URLInfoMap["delSqlSession"], nil, pathParam, nil)
	pt.Reporter.StepReport(fmt.Sprintf("delete sql session %s, path param is %s, status code is %d", sessionId, pathParam, delSqlSessionResp.Raw().StatusCode),
		func() {
			delSqlSessionResp.Status(http.StatusOK)
		})
}

func (pt *PlatformTest) CheckSessionIsClosed(sessionId string, clusterId ...string) {
	util.SecondTimeWait(1, 5, "Wait For Region Message Sync")
	checkSessionCluster := pt.w.Cluster.ClusterId
	if len(clusterId) != 0 {
		checkSessionCluster = clusterId[0]
	}
	pathParam := map[string]string{
		"org_id":     pt.w.User.OrgId,
		"project_id": pt.w.User.ProjectId,
		"cluster_id": checkSessionCluster,
	}

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

	pt.Reporter.StepReport(fmt.Sprintf("check session is closed, 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(),
	),
		func() {
			runSqlResp.JSON().Object().HasValue("code", 60100001)
			runSqlResp.JSON().Path("$.message").String().Contains("your session has expired")
		})
}
