package e2e

import (
	"fmt"
	"log"
)

func ExecRbacCase() {
	RBAC_OrgOwnerCanCreateApiKey()
	RBAC_OrgMemberCanNotCreateApiKey()
	RBAC_OrgBillingAdminCanNotCreateApiKey()
	RBAC_OrgBillingViewerCanNotCreateApiKey()
	RBAC_OrgAuditAdminCanNotCreateApiKey()

	RBAC_OrgOwnerCanCreateProjectApiKey()
	RBAC_ProjectOwnerCanCreateProjectApiKey()
	RBAC_OrgMemberCanNotCreateProjectApiKey()
	RBAC_OrgBillingAdminCanNotCreateProjectApiKey()
	RBAC_OrgBillingViewerCanNotCreateProjectApiKey()
	RBAC_OrgAuditAdminCanNotCreateProjectApiKey()
	RBAC_ProjectCtlPlaneViewerCanNotCreateProjectApiKey()

	RBAC_OrgOwnerCanNotCreateApiKeyInOtherOrg()
	RBAC_OrgOwnerCanNotResetOtherOrgTiDBPassword()
	RBAC_AccessOrgProjectScopeNotMatch()
	RBAC_AccessOrgTiDBScopeNotMatch()

	RBAC_OrgOwnerCanCheckImportSource()
	RBAC_OrgMemberCanNotCheckImportSource()
	RBAC_OrgBillingAdminCanNotCheckImportSource()
	RBAC_OrgBillingViewerCanNotCheckImportSource()
	RBAC_OrgAuditAdminCanNotCheckImportSource()
	// org member on org_id has no permission but cluster admin role on tidb_id has permission (temprarlly use org owner role replace cluster admin)
	RBAC_OrgMemberKeyWithClusterAdminRoleCanCheckImportSource()

	RBAC_OrgOwnerCanGetImportIntoTask()
	RBAC_OrgMemberCanNotGetImportIntoTask()
	RBAC_OrgBillingAdminCanNotGetImportIntoTask()
	RBAC_OrgBillingViewerCanNotGetImportIntoTask()
	RBAC_OrgAuditAdminCanNotGetImportIntoTask()
	RBAC_OrgMemberKeyWithClusterAdminRoleCanGetImportIntoTask()

}

func RBAC_OrgOwnerCanCreateApiKey() {
	url := DevIamOpenApiHost + "/v1beta1/apikeys"

	var header = map[string]string{}
	header["Content-type"] = "application/json"
	header[DigestAuthUserHeader] = orgOwnerKey

	body := `{
		"displayName": "e2e: create api key in org",
		"role": "org:owner"
	}`

	code, data, err := RestyExec("POST", url, header, body)
	if err != nil {
		code = 0
		data = err.Error()
	}

	log.Println(code, data)

	SaveCase("RBAC", "OrgOwnerCanCreateApiKey", CaseDetail{
		Url:       url,
		ReqHeader: header,
		ReqBody:   body,
		Pass:      code == 200,
		RspCode:   code,
		RspData:   data,
	})
}

func RBAC_OrgMemberCanNotCreateApiKey() {
	url := DevIamOpenApiHost + "/v1beta1/apikeys"

	var header = map[string]string{}
	header["Content-type"] = "application/json"
	header[DigestAuthUserHeader] = orgMemberKey

	body := `{
		"displayName": "e2e: create api key in org",
		"role": "org:owner"
	}`

	code, data, err := RestyExec("POST", url, header, body)
	if err != nil {
		code = 0
		data = err.Error()
	}

	log.Println(code, data)

	SaveCase("RBAC", "OrgMemberCanNotCreateApiKey", CaseDetail{
		Url:       url,
		ReqHeader: header,
		ReqBody:   body,
		Pass:      code == 403,
		RspCode:   code,
		RspData:   data,
	})
}

func RBAC_OrgBillingAdminCanNotCreateApiKey() {
	url := DevIamOpenApiHost + "/v1beta1/apikeys"

	var header = map[string]string{}
	header["Content-type"] = "application/json"
	header[DigestAuthUserHeader] = orgBillingAdminKey

	body := `{
		"displayName": "e2e: create api key in org",
		"role": "org:owner"
	}`

	code, data, err := RestyExec("POST", url, header, body)
	if err != nil {
		code = 0
		data = err.Error()
	}

	log.Println(code, data)

	SaveCase("RBAC", "OrgBillingAdminCanNotCreateApiKey", CaseDetail{
		Url:       url,
		ReqHeader: header,
		ReqBody:   body,
		Pass:      code == 403,
		RspCode:   code,
		RspData:   data,
	})
}

func RBAC_OrgBillingViewerCanNotCreateApiKey() {
	url := DevIamOpenApiHost + "/v1beta1/apikeys"

	var header = map[string]string{}
	header["Content-type"] = "application/json"
	header[DigestAuthUserHeader] = orgBillingViewerKey

	body := `{
		"displayName": "e2e: create api key in org",
		"role": "org:owner"
	}`

	code, data, err := RestyExec("POST", url, header, body)
	if err != nil {
		code = 0
		data = err.Error()
	}

	log.Println(code, data)

	SaveCase("RBAC", "OrgBillingViewerCanNotCreateApiKey", CaseDetail{
		Url:       url,
		ReqHeader: header,
		ReqBody:   body,
		Pass:      code == 403,
		RspCode:   code,
		RspData:   data,
	})
}

func RBAC_OrgAuditAdminCanNotCreateApiKey() {
	url := DevIamOpenApiHost + "/v1beta1/apikeys"

	var header = map[string]string{}
	header["Content-type"] = "application/json"
	header[DigestAuthUserHeader] = orgAuditAdminKey

	body := `{
		"displayName": "e2e: create api key in org",
		"role": "org:owner"
	}`

	code, data, err := RestyExec("POST", url, header, body)
	if err != nil {
		code = 0
		data = err.Error()
	}

	log.Println(code, data)

	SaveCase("RBAC", "OrgAuditAdminCanNotCreateApiKey", CaseDetail{
		Url:       url,
		ReqHeader: header,
		ReqBody:   body,
		Pass:      code == 403,
		RspCode:   code,
		RspData:   data,
	})
}

func RBAC_OrgOwnerCanCreateProjectApiKey() {
	url := DevIamOpenApiHost + "/v1beta1/apikeys"

	var header = map[string]string{}
	header["Content-type"] = "application/json"
	header[DigestAuthUserHeader] = orgOwnerKey

	body := `{
		"displayName": "e2e: create api key in org",
		"role": "project:owner",
		"projectId": 3199935
	}`

	code, data, err := RestyExec("POST", url, header, body)
	if err != nil {
		code = 0
		data = err.Error()
	}

	log.Println(code, data)

	SaveCase("RBAC", "OrgOwnerCanCreateProjectApiKey", CaseDetail{
		Url:       url,
		ReqHeader: header,
		ReqBody:   body,
		Pass:      code == 200,
		RspCode:   code,
		RspData:   data,
	})
}

func RBAC_ProjectOwnerCanCreateProjectApiKey() {
	url := DevIamOpenApiHost + "/v1beta1/apikeys"

	var header = map[string]string{}
	header["Content-type"] = "application/json"
	header[DigestAuthUserHeader] = projectOwnerKey

	body := `{
		"displayName": "e2e: create api key in org",
		"role": "project:owner",
		"projectId": 3199935
	}`

	code, data, err := RestyExec("POST", url, header, body)
	if err != nil {
		code = 0
		data = err.Error()
	}

	log.Println(code, data)

	SaveCase("RBAC", "ProjectOwnerCanCreateProjectApiKey", CaseDetail{
		Url:       url,
		ReqHeader: header,
		ReqBody:   body,
		Pass:      code == 200,
		RspCode:   code,
		RspData:   data,
	})
}

func RBAC_OrgMemberCanNotCreateProjectApiKey() {
	url := DevIamOpenApiHost + "/v1beta1/apikeys"

	var header = map[string]string{}
	header["Content-type"] = "application/json"
	header[DigestAuthUserHeader] = orgMemberKey

	body := `{
		"displayName": "e2e: create api key in org",
		"role": "project:owner",
		"projectId": 3199935
	}`

	code, data, err := RestyExec("POST", url, header, body)
	if err != nil {
		code = 0
		data = err.Error()
	}

	log.Println(code, data)

	SaveCase("RBAC", "OrgMemberCanNotCreateProjectApiKey", CaseDetail{
		Url:       url,
		ReqHeader: header,
		ReqBody:   body,
		Pass:      code == 403,
		RspCode:   code,
		RspData:   data,
	})
}

func RBAC_OrgBillingAdminCanNotCreateProjectApiKey() {
	url := DevIamOpenApiHost + "/v1beta1/apikeys"

	var header = map[string]string{}
	header["Content-type"] = "application/json"
	header[DigestAuthUserHeader] = orgBillingAdminKey

	body := `{
		"displayName": "e2e: create api key in org",
		"role": "project:dev",
		"projectId": 3199935
	}`

	code, data, err := RestyExec("POST", url, header, body)
	if err != nil {
		code = 0
		data = err.Error()
	}

	log.Println(code, data)

	SaveCase("RBAC", "OrgBillingAdminCanNotCreateProjectApiKey", CaseDetail{
		Url:       url,
		ReqHeader: header,
		ReqBody:   body,
		Pass:      code == 403,
		RspCode:   code,
		RspData:   data,
	})
}

func RBAC_OrgBillingViewerCanNotCreateProjectApiKey() {
	url := DevIamOpenApiHost + "/v1beta1/apikeys"

	var header = map[string]string{}
	header["Content-type"] = "application/json"
	header[DigestAuthUserHeader] = orgBillingViewerKey

	body := `{
		"displayName": "e2e: create api key in org",
		"role": "project:readonly",
		"projectId": 3199935
	}`

	code, data, err := RestyExec("POST", url, header, body)
	if err != nil {
		code = 0
		data = err.Error()
	}

	log.Println(code, data)

	SaveCase("RBAC", "OrgBillingViewerCanNotCreateProjectApiKey", CaseDetail{
		Url:       url,
		ReqHeader: header,
		ReqBody:   body,
		Pass:      code == 403,
		RspCode:   code,
		RspData:   data,
	})
}

func RBAC_OrgAuditAdminCanNotCreateProjectApiKey() {
	url := DevIamOpenApiHost + "/v1beta1/apikeys"

	var header = map[string]string{}
	header["Content-type"] = "application/json"
	header[DigestAuthUserHeader] = orgAuditAdminKey

	body := `{
		"displayName": "e2e: create api key in org",
		"role": "project:owner",
		"projectId": 3199935
	}`

	code, data, err := RestyExec("POST", url, header, body)
	if err != nil {
		code = 0
		data = err.Error()
	}

	log.Println(code, data)

	SaveCase("RBAC", "OrgAuditAdminCanNotCreateProjectApiKey", CaseDetail{
		Url:       url,
		ReqHeader: header,
		ReqBody:   body,
		Pass:      code == 403,
		RspCode:   code,
		RspData:   data,
	})
}

func RBAC_ProjectCtlPlaneViewerCanNotCreateProjectApiKey() {
	url := DevIamOpenApiHost + "/v1beta1/apikeys"

	var header = map[string]string{}
	header["Content-type"] = "application/json"
	header[DigestAuthUserHeader] = projectCtrlPlaneViewerKey

	body := `{
		"displayName": "e2e: create api key in org",
		"role": "project:owner",
		"projectId": 3199935
	}`

	code, data, err := RestyExec("POST", url, header, body)
	if err != nil {
		code = 0
		data = err.Error()
	}

	log.Println(code, data)

	SaveCase("RBAC", "ProjectCtlPlaneViewerCanNotCreateProjectApiKey", CaseDetail{
		Url:       url,
		ReqHeader: header,
		ReqBody:   body,
		Pass:      code == 403,
		RspCode:   code,
		RspData:   data,
	})
}

func RBAC_OrgOwnerCanNotResetOtherOrgTiDBPassword() {
	url := DevCloudOpenApiHost + "/v1beta2/tidbs/12345:resetRootPassword"

	var header = map[string]string{}
	header["Content-type"] = "application/json"
	header[DigestAuthUserHeader] = orgOwnerKey

	code, data, err := RestyExec("POST", url, header, "")
	if err != nil {
		code = 0
		data = err.Error()
	}

	log.Println(code, data)

	SaveCase("RBAC", "OrgOwnerCanNotResetOtherOrgTiDBPassword", CaseDetail{
		Url:       url,
		ReqHeader: header,
		ReqBody:   "",
		Pass:      code == 403,
		RspCode:   code,
		RspData:   data,
	})
}

func RBAC_OrgOwnerCanNotCreateApiKeyInOtherOrg() {
	url := DevConsoleHost + "/api/v1/orgs/1440003/api_keys"

	var header = map[string]string{}
	header["Content-type"] = "application/json"
	header["authorization"] = consoleAuthorization

	body := `{
		"displayName": "e2e: create api key",
		"role": "org:member"
	}`

	code, data, err := RestyExec("POST", url, header, body)
	if err != nil {
		code = 0
		data = err.Error()
	}

	log.Println(code, data)

	SaveCase("RBAC", "OrgOwnerCanNotCreateApiKeyInOtherOrg", CaseDetail{
		Url:       url,
		ReqHeader: header,
		ReqBody:   body,
		Pass:      code == 401,
		RspCode:   code,
		RspData:   data,
	})
}

func RBAC_AccessOrgTiDBScopeNotMatch() {
	url := DevCloudOpenApiHost + "/v1beta2/tidbs/12345/privateEndpointConnections/111"

	var header = map[string]string{}
	header["Content-type"] = "application/json"
	header[DigestAuthUserHeader] = orgOwnerKey

	code, data, err := RestyExec("DELETE", url, header, "")
	if err != nil {
		code = 0
		data = err.Error()
	}

	log.Println(code, data)

	SaveCase("RBAC", "AccessOrgTiDBScopeNotMatch", CaseDetail{
		Url:       url,
		ReqHeader: header,
		ReqBody:   "",
		Pass:      code == 403,
		RspCode:   code,
		RspData:   data,
	})
}

func RBAC_AccessOrgProjectScopeNotMatch() {
	url := DevConsoleHost + "/api/v1/orgs/1440002/projects/319993500/users"

	var header = map[string]string{}
	header["Content-type"] = "application/json"
	header["authorization"] = consoleAuthorization

	body := `{
		"email": "test@pingcap.com",
		"rbac_role": "project:readonly"
	}`

	code, data, err := RestyExec("POST", url, header, body)
	if err != nil {
		code = 0
		data = err.Error()
	}

	log.Println(code, data)

	SaveCase("RBAC", "AccessOrgProjectScopeNotMatch", CaseDetail{
		Url:       url,
		ReqHeader: header,
		ReqBody:   body,
		Pass:      code == 403,
		RspCode:   code,
		RspData:   data,
	})
}

func RBAC_OrgOwnerCanCheckImportSource() {
	url := DevCloudOpenApiHost + "/v1beta2/tidbs/12345678/imports:checkSource"

	var header = map[string]string{}
	header["Content-type"] = "application/json"
	header[DigestAuthUserHeader] = orgOwnerKey

	body := `{
		"source": {
			"type": 0
		}
	}`

	code, data, err := RestyExec("POST", url, header, body)
	if err != nil {
		code = 0
		data = err.Error()
	}

	log.Println(code, data)

	pass := false
	if code != 401 && code != 403 {
		pass = true
	}
	SaveCase("RBAC", "OrgOwnerCanCheckImportSource", CaseDetail{
		Url:       url,
		Method:    "POST",
		ReqHeader: header,
		ReqBody:   body,
		Pass:      pass,
		RspCode:   code,
		RspData:   data,
	})
}

func RBAC_OrgMemberCanNotCheckImportSource() {
	url := DevCloudOpenApiHost + "/v1beta2/tidbs/12345678/imports:checkSource"

	var header = map[string]string{}
	header["Content-type"] = "application/json"
	header[DigestAuthUserHeader] = orgMemberKey

	body := `{
		"source": {
			"type": 0
		}
	}`

	code, data, err := RestyExec("POST", url, header, body)
	if err != nil {
		code = 0
		data = err.Error()
	}

	log.Println(code, data)

	SaveCase("RBAC", "OrgMemberCanNotCheckImportSource", CaseDetail{
		Url:       url,
		Method:    "POST",
		ReqHeader: header,
		ReqBody:   body,
		Pass:      code == 403,
		RspCode:   code,
		RspData:   data,
	})
}

func RBAC_OrgBillingAdminCanNotCheckImportSource() {
	url := DevCloudOpenApiHost + "/v1beta2/tidbs/12345678/imports:checkSource"

	var header = map[string]string{}
	header["Content-type"] = "application/json"
	header[DigestAuthUserHeader] = orgBillingAdminKey

	body := `{
		"source": {
			"type": 0
		}
	}`

	code, data, err := RestyExec("POST", url, header, body)
	if err != nil {
		code = 0
		data = err.Error()
	}

	log.Println(code, data)

	SaveCase("RBAC", "OrgBillingAdminCanNotCheckImportSource", CaseDetail{
		Url:       url,
		Method:    "POST",
		ReqHeader: header,
		ReqBody:   body,
		Pass:      code == 403,
		RspCode:   code,
		RspData:   data,
	})
}

func RBAC_OrgBillingViewerCanNotCheckImportSource() {
	url := DevCloudOpenApiHost + "/v1beta2/tidbs/12345678/imports:checkSource"

	var header = map[string]string{}
	header["Content-type"] = "application/json"
	header[DigestAuthUserHeader] = orgBillingViewerKey

	body := `{
		"source": {
			"type": 0
		}
	}`

	code, data, err := RestyExec("POST", url, header, body)
	if err != nil {
		code = 0
		data = err.Error()
	}

	log.Println(code, data)

	SaveCase("RBAC", "OrgBillingViewerCanNotCheckImportSource", CaseDetail{
		Url:       url,
		Method:    "POST",
		ReqHeader: header,
		ReqBody:   body,
		Pass:      code == 403,
		RspCode:   code,
		RspData:   data,
	})
}

func RBAC_OrgAuditAdminCanNotCheckImportSource() {
	url := DevCloudOpenApiHost + "/v1beta2/tidbs/12345678/imports:checkSource"

	var header = map[string]string{}
	header["Content-type"] = "application/json"
	header[DigestAuthUserHeader] = orgAuditAdminKey

	body := `{
		"source": {
			"type": 0
		}
	}`

	code, data, err := RestyExec("POST", url, header, body)
	if err != nil {
		code = 0
		data = err.Error()
	}

	log.Println(code, data)

	SaveCase("RBAC", "OrgAuditAdminCanNotCheckImportSource", CaseDetail{
		Url:       url,
		Method:    "POST",
		ReqHeader: header,
		ReqBody:   body,
		Pass:      code == 403,
		RspCode:   code,
		RspData:   data,
	})
}

func RBAC_OrgMemberKeyWithClusterAdminRoleCanCheckImportSource() {
	url := DevCloudOpenApiHost + fmt.Sprintf("/v1beta2/tidbs/%d/imports:checkSource", clusterId)

	var header = map[string]string{}
	header["Content-type"] = "application/json"
	header[DigestAuthUserHeader] = orgMemberWithClusterAdminRoleKey

	body := `{
		"source": {
			"type": 0
		}
	}`

	code, data, err := RestyExec("POST", url, header, body)
	if err != nil {
		code = 0
		data = err.Error()
	}

	log.Println(code, data)

	pass := false
	if code != 401 && code != 403 {
		pass = true
	}
	SaveCase("RBAC", "OrgMemberKeyWithClusterAdminRoleCanCheckImportSource", CaseDetail{
		Url:       url,
		Method:    "POST",
		ReqHeader: header,
		ReqBody:   body,
		Pass:      pass,
		RspCode:   code,
		RspData:   data,
	})
}

func RBAC_OrgOwnerCanGetImportIntoTask() {
	url := DevCloudOpenApiHost + "/v1beta2/tidbs/12345678/imports/1"

	var header = map[string]string{}
	header["Content-type"] = "application/json"
	header[DigestAuthUserHeader] = orgOwnerKey

	code, data, err := RestyExec("GET", url, header, "")
	if err != nil {
		code = 0
		data = err.Error()
	}

	log.Println(code, data)

	pass := false
	if code != 401 && code != 403 {
		pass = true
	}
	SaveCase("RBAC", "OrgOwnerCanGetImportIntoTask", CaseDetail{
		Url:       url,
		Method:    "GET",
		ReqHeader: header,
		ReqBody:   "",
		Pass:      pass,
		RspCode:   code,
		RspData:   data,
	})
}

func RBAC_OrgMemberCanNotGetImportIntoTask() {
	url := DevCloudOpenApiHost + "/v1beta2/tidbs/12345678/imports/1"

	var header = map[string]string{}
	header["Content-type"] = "application/json"
	header[DigestAuthUserHeader] = orgMemberKey

	code, data, err := RestyExec("GET", url, header, "")
	if err != nil {
		code = 0
		data = err.Error()
	}

	log.Println(code, data)

	SaveCase("RBAC", "OrgMemberCanNotGetImportIntoTask", CaseDetail{
		Url:       url,
		Method:    "GET",
		ReqHeader: header,
		ReqBody:   "",
		Pass:      code == 403,
		RspCode:   code,
		RspData:   data,
	})
}

func RBAC_OrgBillingAdminCanNotGetImportIntoTask() {
	url := DevCloudOpenApiHost + "/v1beta2/tidbs/12345678/imports/1"

	var header = map[string]string{}
	header["Content-type"] = "application/json"
	header[DigestAuthUserHeader] = orgBillingAdminKey

	code, data, err := RestyExec("GET", url, header, "")
	if err != nil {
		code = 0
		data = err.Error()
	}

	log.Println(code, data)

	SaveCase("RBAC", "OrgBillingAdminCanNotGetImportIntoTask", CaseDetail{
		Url:       url,
		Method:    "GET",
		ReqHeader: header,
		ReqBody:   "",
		Pass:      code == 403,
		RspCode:   code,
		RspData:   data,
	})
}

func RBAC_OrgBillingViewerCanNotGetImportIntoTask() {
	url := DevCloudOpenApiHost + "/v1beta2/tidbs/12345678/imports/1"

	var header = map[string]string{}
	header["Content-type"] = "application/json"
	header[DigestAuthUserHeader] = orgBillingViewerKey

	code, data, err := RestyExec("GET", url, header, "")
	if err != nil {
		code = 0
		data = err.Error()
	}

	log.Println(code, data)

	SaveCase("RBAC", "OrgBillingViewerCanNotGetImportIntoTask", CaseDetail{
		Url:       url,
		Method:    "GET",
		ReqHeader: header,
		ReqBody:   "",
		Pass:      code == 403,
		RspCode:   code,
		RspData:   data,
	})
}

func RBAC_OrgAuditAdminCanNotGetImportIntoTask() {
	url := DevCloudOpenApiHost + "/v1beta2/tidbs/12345678/imports/1"

	var header = map[string]string{}
	header["Content-type"] = "application/json"
	header[DigestAuthUserHeader] = orgBillingViewerKey

	code, data, err := RestyExec("GET", url, header, "")
	if err != nil {
		code = 0
		data = err.Error()
	}

	log.Println(code, data)

	SaveCase("RBAC", "OrgAuditAdminCanNotGetImportIntoTask", CaseDetail{
		Url:       url,
		Method:    "GET",
		ReqHeader: header,
		ReqBody:   "",
		Pass:      code == 403,
		RspCode:   code,
		RspData:   data,
	})
}

func RBAC_OrgMemberKeyWithClusterAdminRoleCanGetImportIntoTask() {
	url := DevCloudOpenApiHost + fmt.Sprintf("/v1beta2/tidbs/%d/imports/1", clusterId)

	var header = map[string]string{}
	header["Content-type"] = "application/json"
	header[DigestAuthUserHeader] = orgMemberWithClusterAdminRoleKey

	code, data, err := RestyExec("GET", url, header, "")
	if err != nil {
		code = 0
		data = err.Error()
	}

	log.Println(code, data)

	pass := false
	if code != 401 && code != 403 {
		pass = true
	}
	SaveCase("RBAC", "OrgMemberKeyWithClusterAdminRoleCanGetImportIntoTask", CaseDetail{
		Url:       url,
		Method:    "GET",
		ReqHeader: header,
		ReqBody:   "",
		Pass:      pass,
		RspCode:   code,
		RspData:   data,
	})
}
