package platform

import (
	"fmt"
	"net/http"

	l4g "github.com/alecthomas/log4go"
	"github.com/gavv/httpexpect/v2"
)

type DataAPIDBOperation struct {
	Pt        *PlatformTest
	SessionId string
}

func (dbo *DataAPIDBOperation) CreateDB(dbName string) {
	// create database
	sql := fmt.Sprintf("create database if not exists %s;", dbName)
	body := map[string]string{
		"sql":       sql,
		"sessionid": dbo.SessionId,
	}
	pathParam := map[string]string{
		"org_id":     dbo.Pt.w.User.OrgId,
		"project_id": dbo.Pt.w.User.ProjectId,
		"cluster_id": dbo.Pt.w.Cluster.ClusterId,
	}
	dbo.Pt.w.DoWebAPIRequestByUrlInfo(dbo.Pt.URLInfoMap["executeSql"], body, pathParam, nil)
}

// This func only do `use dbName`, wont do `create database dbName`.
func (dbo *DataAPIDBOperation) CreateTableAfterUseDB(dbName string, table_sql string) {
	// use db in session
	use_sql := fmt.Sprintf("use %s;", dbName)
	body := map[string]string{"sql": use_sql, "sessionid": dbo.SessionId}
	pathParam := map[string]string{
		"org_id":     dbo.Pt.w.User.OrgId,
		"project_id": dbo.Pt.w.User.ProjectId,
		"cluster_id": dbo.Pt.w.Cluster.ClusterId,
	}
	dbo.Pt.w.DoWebAPIRequestByUrlInfo(dbo.Pt.URLInfoMap["executeSql"], body, pathParam, nil)

	// create table in db
	l4g.Info("table_sql is %s", table_sql)
	body = map[string]string{"sql": table_sql, "sessionid": dbo.SessionId}
	dbo.Pt.w.DoWebAPIRequestByUrlInfo(dbo.Pt.URLInfoMap["executeSql"], body, pathParam, nil)
}

// This func executes the sql directly, so make sure your sql is correct.
func (dbo *DataAPIDBOperation) ExecuteSql(execute_sql string, dbName ...string) {
	// execute sql
	l4g.Info("execute_sql is %s", execute_sql)
	body := map[string]string{
		"sql":       execute_sql,
		"sessionid": dbo.SessionId,
	}
	if len(dbName) > 0 {
		body["database"] = dbName[0]
	}
	pathParam := map[string]string{
		"org_id":     dbo.Pt.w.User.OrgId,
		"project_id": dbo.Pt.w.User.ProjectId,
		"cluster_id": dbo.Pt.w.Cluster.ClusterId,
	}
	dbo.Pt.w.DoWebAPIRequestByUrlInfo(dbo.Pt.URLInfoMap["executeSql"], body, pathParam, nil)
}

// run sql with db and return *httpexpect.Array
func (dbo *DataAPIDBOperation) ExecuteSqlAndGetRows(execute_sql string, dbName ...string) *httpexpect.Array {
	body := map[string]string{
		"sql":       execute_sql,
		"sessionid": dbo.SessionId,
	}
	if len(dbName) > 0 {
		body["database"] = dbName[0]
	}
	// execute sql
	pathParam := map[string]string{
		"org_id":     dbo.Pt.w.User.OrgId,
		"project_id": dbo.Pt.w.User.ProjectId,
		"cluster_id": dbo.Pt.w.Cluster.ClusterId,
	}
	runSqlResp := dbo.Pt.w.DoWebAPIRequestByUrlInfo(dbo.Pt.URLInfoMap["executeSql"], body, pathParam, nil)
	runSqlResp.Status(http.StatusOK)

	// get result
	rows := runSqlResp.JSON().Path(DataRowsPath).Array()
	return rows
}

// This func executes SQL and return *httpexpect.Response.
func (dbo *DataAPIDBOperation) ExecuteSqlAndGetResponse(execute_sql string, dbName ...string) *httpexpect.Response {
	// execute sql
	l4g.Info("execute_sql is %s", execute_sql)
	body := map[string]string{
		"sql":       execute_sql,
		"sessionid": dbo.SessionId,
	}
	if len(dbName) > 0 {
		body["database"] = dbName[0]
	}
	pathParam := map[string]string{
		"org_id":     dbo.Pt.w.User.OrgId,
		"project_id": dbo.Pt.w.User.ProjectId,
		"cluster_id": dbo.Pt.w.Cluster.ClusterId,
	}
	runSqlResp := dbo.Pt.w.DoWebAPIRequestByUrlInfo(dbo.Pt.URLInfoMap["executeSql"], body, pathParam, nil)

	return runSqlResp
}
