package e2e

import (
	"encoding/json"
	"fmt"
	"strings"
)

func ExecCentralProjectCase() {
	Central_CreateProject()
	Central_CreateTiDBXProject()
	Central_ListProjects()
	Central_ListProjectsByTypeTiDBX()
	Central_ListOrgProjects()
	Central_ListOrgProjectsByType()
	Central_UpdateProject()
	Central_DeleteProject()

}

func Central_CreateProject() {
	url := DevConsoleHost + "/api/v1/orgs/1440002/projects"
	var header = map[string]string{}
	header["Content-type"] = "application/json"
	header["Authorization"] = consoleAuthorization
	name := fmt.Sprintf("e2e-p-%s", CurTimeStr())
	body := fmt.Sprintf(`{
			"name": "%s",
			"aws_cmek_enabled": true
		}`, name)
	code, data, err := RestyExec("POST", url, header, body)
	if err != nil {
		code = 0
		data = err.Error()
	}
	var pid string
	if code == 200 {
		var pidI = &ProjectId{}
		err := json.Unmarshal([]byte(data), pidI)
		if err == nil {
			pid = pidI.Id
		}
	}

	pass := false
	listUrl := DevConsoleHost + "/api/v1/orgs/1440002/projects"
	listCode, listData, listErr := RestyExec("GET", listUrl, header, "")
	if listErr != nil {
		listCode = 0
		listData = listErr.Error()
	}
	if listCode == 200 {
		ps := &Projects{}
		err := json.Unmarshal([]byte(listData), ps)
		if err == nil {
			for _, p := range ps.Items {
				if p.Id == pid && p.Name == name && p.Type == "dedicated" {
					pass = true
					break
				}
			}
		}
	}

	SaveCase("Central_Project", "CreateProject", CaseDetail{
		Url:       url,
		Method:    "POST",
		ReqHeader: header,
		ReqBody:   body,
		Pass:      pass,
		RspCode:   code,
		RspData:   data,
		Extra: map[string]interface{}{
			"list_url":  listUrl,
			"list_code": listCode,
			"list_data": listData,
		},
	})
}

func Central_CreateTiDBXProject() {
	url := DevConsoleHost + "/api/v1/orgs/1440002/projects"
	var header = map[string]string{}
	header["Content-type"] = "application/json"
	header["Authorization"] = consoleAuthorization
	name := fmt.Sprintf("e2e-tidbx-%s", CurTimeStr())
	body := fmt.Sprintf(`{
			"name": "%s",
			"type": "tidbx"
		}`, name)
	code, data, err := RestyExec("POST", url, header, body)
	if err != nil {
		code = 0
		data = err.Error()
	}
	var pid string
	if code == 200 {
		var pidI = &ProjectId{}
		err := json.Unmarshal([]byte(data), pidI)
		if err == nil {
			pid = pidI.Id
		}
	}

	pass := false
	listUrl := DevConsoleHost + "/api/v1/orgs/1440002/projects?types=tidbx"
	listCode, listData, listErr := RestyExec("GET", listUrl, header, "")
	if listErr != nil {
		listCode = 0
		listData = listErr.Error()
	}
	if listCode == 200 {
		ps := &Projects{}
		err := json.Unmarshal([]byte(listData), ps)
		if err == nil {
			for _, p := range ps.Items {
				if p.Id == pid && p.Name == name && p.Type == "tidbx" {
					pass = true
					break
				}
			}
		}
	}

	SaveCase("Central_Project", "CreateTiDBXProject", CaseDetail{
		Url:       url,
		Method:    "POST",
		ReqHeader: header,
		ReqBody:   body,
		Pass:      pass,
		RspCode:   code,
		RspData:   data,
		Extra: map[string]interface{}{
			"list_url":  listUrl,
			"list_code": listCode,
			"list_data": listData,
		},
	})
}

type ProjectId struct {
	Id string `json:"id,omitempty"`
}

type Projects struct {
	Total int32      `json:"total,omitempty"`
	Items []*Project `json:"items,omitempty"`
}

type Project struct {
	Id                  string `json:"id,omitempty"`
	Name                string `json:"name,omitempty"`
	ActiveClustersCount int32  `json:"active_clusters_count,omitempty"`
	UsersCount          uint32 `json:"users_count,omitempty"`
	AwsCmekEnabled      bool   `json:"aws_cmek_enabled,omitempty"`
	Type                string `json:"type,omitempty"`
}

func Central_ListProjects() {
	listUrl := DevConsoleHost + "/api/v1/orgs/1440002/projects?page=1&per_page=2&types=dedicated"
	var header = map[string]string{}
	header["Content-type"] = "application/json"
	header["Authorization"] = consoleAuthorization
	listCode, listData, listErr := RestyExec("GET", listUrl, header, "")
	if listErr != nil {
		listCode = 0
		listData = listErr.Error()
	}
	pass := false
	if listCode == 200 {
		ps := &Projects{}
		err := json.Unmarshal([]byte(listData), ps)
		if err == nil && len(ps.Items) <= 2 {
			allDedicated := true
			for _, item := range ps.Items {
				if item.Type != "dedicated" {
					allDedicated = false
					break
				}
			}
			pass = allDedicated
		}
	}
	SaveCase("Central_Project", "ListProjects", CaseDetail{
		Url:       listUrl,
		Method:    "GET",
		ReqHeader: header,
		ReqBody:   "",
		Pass:      pass,
		RspCode:   listCode,
		RspData:   listData,
	})
}

func Central_ListProjectsByTypeTiDBX() {
	listUrl := DevConsoleHost + "/api/v1/orgs/1440002/projects?types=tidbx"
	var header = map[string]string{}
	header["Content-type"] = "application/json"
	header["Authorization"] = consoleAuthorization
	listCode, listData, listErr := RestyExec("GET", listUrl, header, "")
	if listErr != nil {
		listCode = 0
		listData = listErr.Error()
	}
	pass := false
	if listCode == 200 {
		ps := &Projects{}
		err := json.Unmarshal([]byte(listData), ps)
		if err == nil {
			allTiDBX := true
			for _, item := range ps.Items {
				if item.Type != "tidbx" {
					allTiDBX = false
					break
				}
			}
			pass = allTiDBX
		}
	}
	SaveCase("Central_Project", "ListProjectsByTypeTiDBX", CaseDetail{
		Url:       listUrl,
		Method:    "GET",
		ReqHeader: header,
		ReqBody:   "",
		Pass:      pass,
		RspCode:   listCode,
		RspData:   listData,
	})
}

func Central_UpdateProject() {
	listUrl := DevConsoleHost + "/api/v1/orgs/1440002/projects?page=1&per_page=2"
	var header = map[string]string{}
	header["Content-type"] = "application/json"
	header["Authorization"] = consoleAuthorization
	listCode, listData, listErr := RestyExec("GET", listUrl, header, "")
	if listErr != nil {
		listCode = 0
		listData = listErr.Error()
	}
	var p *Project
	if listCode == 200 {
		ps := &Projects{}
		err := json.Unmarshal([]byte(listData), ps)
		if err == nil && len(ps.Items) > 0 {
			p = ps.Items[0]
		}
	}
	var updateUrl, updateData string
	var updateCode int
	name := fmt.Sprintf("e2e-update-%s", CurTimeStr())
	updateBody := fmt.Sprintf(`{
		"name": "%s"
	}`, name)
	if p != nil {
		updateUrl = DevConsoleHost + fmt.Sprintf("/api/v1/orgs/1440002/projects/%s", p.Id)
		updateCode, updateData, listErr = RestyExec("PATCH", updateUrl, header, updateBody)
		if listErr != nil {
			updateCode = 0
			updateData = listErr.Error()
		}
	}
	var secListUrl, secListData string
	var secListCode int
	pass := false
	if updateCode == 200 {
		secListUrl = DevConsoleHost + "/api/v1/orgs/1440002/projects"
		secListCode, secListData, listErr = RestyExec("GET", secListUrl, header, "")
		if listErr != nil {
			secListCode = 0
			secListData = listErr.Error()
		}
		if secListCode == 200 {
			ps := &Projects{}
			err := json.Unmarshal([]byte(secListData), ps)
			if err == nil {
				for _, lp := range ps.Items {
					if lp.Id == p.Id && lp.Name == name && lp.Type == p.Type {
						pass = true
						break
					}
				}
			}
		}
	}

	SaveCase("Central_Project", "UpdateProject", CaseDetail{
		Url:       updateUrl,
		Method:    "PATCH",
		ReqHeader: header,
		ReqBody:   updateBody,
		Pass:      pass,
		RspCode:   updateCode,
		RspData:   updateData,
		Extra: map[string]interface{}{
			"list_url":         listUrl,
			"list_code":        listCode,
			"list_data":        listData,
			"second_list_url":  secListUrl,
			"second_list_code": secListCode,
			"second_list_data": secListData,
		},
	})
}

func Central_DeleteProject() {
	listUrl := DevConsoleHost + "/api/v1/orgs/1440002/projects"
	var header = map[string]string{}
	header["Content-type"] = "application/json"
	header["Authorization"] = consoleAuthorization
	listCode, listData, listErr := RestyExec("GET", listUrl, header, "")
	if listErr != nil {
		listCode = 0
		listData = listErr.Error()
	}
	var p *Project
	if listCode == 200 {
		ps := &Projects{}
		err := json.Unmarshal([]byte(listData), ps)
		if err == nil && len(ps.Items) > 0 {
			for _, lp := range ps.Items {
				if strings.HasPrefix(lp.Name, "e2e") {
					p = lp
				}
			}
		}
	}
	var deleteUrl, deleteData string
	var deleteCode int
	var pass = false
	if p != nil {
		deleteUrl = DevConsoleHost + fmt.Sprintf("/api/v1/orgs/1440002/projects/%s", p.Id)
		deleteCode, deleteData, listErr = RestyExec("DELETE", deleteUrl, header, "")
		if listErr != nil {
			deleteCode = 0
			deleteData = listErr.Error()
		}
		if deleteCode == 200 {
			pass = true
		}
	}
	SaveCase("Central_Project", "DeleteProject", CaseDetail{
		Url:       deleteUrl,
		Method:    "DELETE",
		ReqHeader: header,
		ReqBody:   "",
		Pass:      pass,
		RspCode:   deleteCode,
		RspData:   deleteData,
		Extra: map[string]interface{}{
			"list_url":  listUrl,
			"list_code": listCode,
			"list_data": listData,
		},
	})

}

func Central_ListOrgProjects() {
	listUrl := DevConsoleHost + "/api/v1/orgs/1440002/org_projects"
	var header = map[string]string{}
	header["Content-type"] = "application/json"
	header["Authorization"] = consoleAuthorization
	listCode, listData, listErr := RestyExec("GET", listUrl, header, "")
	if listErr != nil {
		listCode = 0
		listData = listErr.Error()
	}
	pass := false
	if listCode == 200 {
		ps := &Projects{}
		err := json.Unmarshal([]byte(listData), ps)
		if err == nil && ps.Total >= 0 {
			pass = true
		}
	}
	SaveCase("Central_Project", "ListOrgProjects", CaseDetail{
		Url:       listUrl,
		Method:    "GET",
		ReqHeader: header,
		ReqBody:   "",
		Pass:      pass,
		RspCode:   listCode,
		RspData:   listData,
	})
}

func Central_ListOrgProjectsByType() {
	listUrl := DevConsoleHost + "/api/v1/orgs/1440002/org_projects?types=dedicated"
	var header = map[string]string{}
	header["Content-type"] = "application/json"
	header["Authorization"] = consoleAuthorization
	listCode, listData, listErr := RestyExec("GET", listUrl, header, "")
	if listErr != nil {
		listCode = 0
		listData = listErr.Error()
	}
	pass := false
	if listCode == 200 {
		ps := &Projects{}
		err := json.Unmarshal([]byte(listData), ps)
		if err == nil {
			allDedicated := true
			for _, item := range ps.Items {
				if item.Type != "dedicated" {
					allDedicated = false
					break
				}
			}
			pass = allDedicated
		}
	}
	SaveCase("Central_Project", "ListOrgProjectsByType", CaseDetail{
		Url:       listUrl,
		Method:    "GET",
		ReqHeader: header,
		ReqBody:   "",
		Pass:      pass,
		RspCode:   listCode,
		RspData:   listData,
	})
}
