//
// This file generated by rdl 1.5.2
//

package msd

import (
	"bytes"
	"encoding/json"
	"fmt"
	rdl "github.com/ardielle/ardielle-go/rdl"
	"io"
	"io/ioutil"
	"net/http"
	"net/url"
	"strconv"
	"strings"
	"time"
)

var _ = json.Marshal
var _ = fmt.Printf
var _ = rdl.BaseTypeAny
var _ = ioutil.NopCloser

type MSDClient struct {
	URL             string
	Transport       http.RoundTripper
	CredsHeaders    map[string]string
	Timeout         time.Duration
	DisableRedirect bool
}

// NewClient creates and returns a new HTTP client object for the MSD service
func NewClient(url string, transport http.RoundTripper) MSDClient {
	return MSDClient{url, transport, make(map[string]string), 0, false}
}

// AddCredentials adds the credentials to the client for subsequent requests.
func (client *MSDClient) AddCredentials(header string, token string) {
	client.CredsHeaders[header] = token
}

func (client MSDClient) getClient() *http.Client {
	var c *http.Client
	if client.Transport != nil {
		c = &http.Client{Transport: client.Transport}
	} else {
		c = &http.Client{}
	}
	if client.DisableRedirect {
		c.CheckRedirect = func(req *http.Request, via []*http.Request) error {
			return http.ErrUseLastResponse
		}
	}
	if client.Timeout > 0 {
		c.Timeout = client.Timeout
	}
	return c
}

func (client MSDClient) addAuthHeader(req *http.Request) {
	if len(client.CredsHeaders) == 0 {
		return
	}
	for key, value := range client.CredsHeaders {
		if strings.HasPrefix(key, "Cookie.") {
			req.Header.Add("Cookie", (key)[7:]+"="+value)
		} else {
			req.Header.Add(key, value)
		}
	}
}

func (client MSDClient) httpGet(url string, headers map[string]string) (*http.Response, error) {
	hclient := client.getClient()
	req, err := http.NewRequest("GET", url, nil)
	if err != nil {
		return nil, err
	}
	client.addAuthHeader(req)
	if headers != nil {
		for k, v := range headers {
			req.Header.Add(k, v)
		}
	}
	return hclient.Do(req)
}

func (client MSDClient) httpDelete(url string, headers map[string]string) (*http.Response, error) {
	hclient := client.getClient()
	req, err := http.NewRequest("DELETE", url, nil)
	if err != nil {
		return nil, err
	}
	client.addAuthHeader(req)
	if headers != nil {
		for k, v := range headers {
			req.Header.Add(k, v)
		}
	}
	return hclient.Do(req)
}

func (client MSDClient) httpPut(url string, headers map[string]string, body []byte) (*http.Response, error) {
	var contentReader io.Reader
	if body != nil {
		contentReader = bytes.NewReader(body)
	}
	hclient := client.getClient()
	req, err := http.NewRequest("PUT", url, contentReader)
	if err != nil {
		return nil, err
	}
	req.Header.Add("Content-type", "application/json")
	client.addAuthHeader(req)
	if headers != nil {
		for k, v := range headers {
			req.Header.Add(k, v)
		}
	}
	return hclient.Do(req)
}

func (client MSDClient) httpPostWithContentType(url string, headers map[string]string, body []byte, contentType string) (*http.Response, error) {
	var contentReader io.Reader
	if body != nil {
		contentReader = bytes.NewReader(body)
	}
	hclient := client.getClient()
	req, err := http.NewRequest("POST", url, contentReader)
	if err != nil {
		return nil, err
	}
	req.Header.Add("Content-type", contentType)
	client.addAuthHeader(req)
	if headers != nil {
		for k, v := range headers {
			req.Header.Add(k, v)
		}
	}
	return hclient.Do(req)
}

func (client MSDClient) httpPost(url string, headers map[string]string, body []byte) (*http.Response, error) {
	return client.httpPostWithContentType(url, headers, body, "application/json")
}

func (client MSDClient) httpPatch(url string, headers map[string]string, body []byte) (*http.Response, error) {
	var contentReader io.Reader
	if body != nil {
		contentReader = bytes.NewReader(body)
	}
	hclient := client.getClient()
	req, err := http.NewRequest("PATCH", url, contentReader)
	if err != nil {
		return nil, err
	}
	req.Header.Add("Content-type", "application/json")
	client.addAuthHeader(req)
	if headers != nil {
		for k, v := range headers {
			req.Header.Add(k, v)
		}
	}
	return hclient.Do(req)
}

func (client MSDClient) httpOptions(url string, headers map[string]string, body []byte) (*http.Response, error) {
	var contentReader io.Reader = nil
	if body != nil {
		contentReader = bytes.NewReader(body)
	}
	hclient := client.getClient()
	req, err := http.NewRequest("OPTIONS", url, contentReader)
	if err != nil {
		return nil, err
	}
	if contentReader != nil {
		req.Header.Add("Content-type", "application/json")
	}
	client.addAuthHeader(req)
	if headers != nil {
		for k, v := range headers {
			req.Header.Add(k, v)
		}
	}
	return hclient.Do(req)
}

func encodeStringParam(name string, val string, def string) string {
	if val == def {
		return ""
	}
	return "&" + name + "=" + url.QueryEscape(val)
}
func encodeBoolParam(name string, b bool, def bool) string {
	if b == def {
		return ""
	}
	return fmt.Sprintf("&%s=%v", name, b)
}
func encodeInt8Param(name string, i int8, def int8) string {
	if i == def {
		return ""
	}
	return "&" + name + "=" + strconv.Itoa(int(i))
}
func encodeInt16Param(name string, i int16, def int16) string {
	if i == def {
		return ""
	}
	return "&" + name + "=" + strconv.Itoa(int(i))
}
func encodeInt32Param(name string, i int32, def int32) string {
	if i == def {
		return ""
	}
	return "&" + name + "=" + strconv.Itoa(int(i))
}
func encodeInt64Param(name string, i int64, def int64) string {
	if i == def {
		return ""
	}
	return "&" + name + "=" + strconv.FormatInt(i, 10)
}
func encodeTimestampParam(name string, i rdl.Timestamp, def rdl.Timestamp) string {
	if i == def {
		return ""
	}
	return "&" + name + "=" + url.QueryEscape(i.String())
}
func encodeUUIDParam(name string, i rdl.UUID, def rdl.UUID) string {
	if i.Equal(def) {
		return ""
	}
	return "&" + name + "=" + i.String()
}
func encodeFloat32Param(name string, i float32, def float32) string {
	if i == def {
		return ""
	}
	return "&" + name + "=" + strconv.FormatFloat(float64(i), 'g', -1, 32)
}
func encodeFloat64Param(name string, i float64, def float64) string {
	if i == def {
		return ""
	}
	return "&" + name + "=" + strconv.FormatFloat(i, 'g', -1, 64)
}
func encodeOptionalEnumParam(name string, e interface{}) string {
	if e == nil {
		return "\"\""
	}
	return fmt.Sprintf("&%s=%v", name, e)
}
func encodeOptionalBoolParam(name string, b *bool) string {
	if b == nil {
		return ""
	}
	return fmt.Sprintf("&%s=%v", name, *b)
}
func encodeOptionalInt32Param(name string, i *int32) string {
	if i == nil {
		return ""
	}
	return "&" + name + "=" + strconv.Itoa(int(*i))
}
func encodeOptionalInt64Param(name string, i *int64) string {
	if i == nil {
		return ""
	}
	return "&" + name + "=" + strconv.Itoa(int(*i))
}
func encodeOptionalTimestampParam(name string, i *rdl.Timestamp) string {
	if i == nil {
		return ""
	}
	return "&" + name + "=" + url.QueryEscape(i.String())
}
func encodeOptionalUUIDParam(name string, i *rdl.UUID) string {
	if i == nil {
		return ""
	}
	return "&" + name + "=" + i.String()
}
func encodeParams(objs ...string) string {
	s := strings.Join(objs, "")
	if s == "" {
		return s
	}
	return "?" + s[1:]
}

func (client MSDClient) PostAthenzDependencyRequest(request *AthenzDependencyRequest) (*AthenzDependencyResponse, error) {
	var data *AthenzDependencyResponse
	url := client.URL + "/domains/dependency-check"
	contentBytes, err := json.Marshal(request)
	if err != nil {
		return data, err
	}
	resp, err := client.httpPost(url, nil, contentBytes)
	if err != nil {
		return data, err
	}
	defer resp.Body.Close()
	switch resp.StatusCode {
	case 200:
		err = json.NewDecoder(resp.Body).Decode(&data)
		if err != nil {
			return data, err
		}
		return data, nil
	default:
		var errobj rdl.ResourceError
		contentBytes, err = io.ReadAll(resp.Body)
		if err != nil {
			return data, err
		}
		json.Unmarshal(contentBytes, &errobj)
		if errobj.Code == 0 {
			errobj.Code = resp.StatusCode
		}
		if errobj.Message == "" {
			errobj.Message = string(contentBytes)
		}
		return data, errobj
	}
}

func (client MSDClient) GetTransportPolicyRules(matchingTag string) (*TransportPolicyRules, string, error) {
	var data *TransportPolicyRules
	headers := map[string]string{
		"If-None-Match": matchingTag,
	}
	url := client.URL + "/transportpolicies"
	resp, err := client.httpGet(url, headers)
	if err != nil {
		return nil, "", err
	}
	defer resp.Body.Close()
	switch resp.StatusCode {
	case 200, 304:
		if 304 != resp.StatusCode {
			err = json.NewDecoder(resp.Body).Decode(&data)
			if err != nil {
				return nil, "", err
			}
		}
		tag := resp.Header.Get(rdl.FoldHttpHeaderName("ETag"))
		return data, tag, nil
	default:
		var errobj rdl.ResourceError
		contentBytes, err := io.ReadAll(resp.Body)
		if err != nil {
			return nil, "", err
		}
		json.Unmarshal(contentBytes, &errobj)
		if errobj.Code == 0 {
			errobj.Code = resp.StatusCode
		}
		if errobj.Message == "" {
			errobj.Message = string(contentBytes)
		}
		return nil, "", errobj
	}
}

func (client MSDClient) ValidateTransportPolicy(transportPolicy *TransportPolicyValidationRequest) (*TransportPolicyValidationResponse, error) {
	var data *TransportPolicyValidationResponse
	url := client.URL + "/transportpolicy/validate"
	contentBytes, err := json.Marshal(transportPolicy)
	if err != nil {
		return data, err
	}
	resp, err := client.httpPost(url, nil, contentBytes)
	if err != nil {
		return data, err
	}
	defer resp.Body.Close()
	switch resp.StatusCode {
	case 200:
		err = json.NewDecoder(resp.Body).Decode(&data)
		if err != nil {
			return data, err
		}
		return data, nil
	default:
		var errobj rdl.ResourceError
		contentBytes, err = io.ReadAll(resp.Body)
		if err != nil {
			return data, err
		}
		json.Unmarshal(contentBytes, &errobj)
		if errobj.Code == 0 {
			errobj.Code = resp.StatusCode
		}
		if errobj.Message == "" {
			errobj.Message = string(contentBytes)
		}
		return data, errobj
	}
}

func (client MSDClient) GetTransportPolicyValidationStatus(domainName DomainName) (*TransportPolicyValidationResponseList, error) {
	var data *TransportPolicyValidationResponseList
	url := client.URL + "/domain/" + fmt.Sprint(domainName) + "/transportpolicy/validationstatus"
	resp, err := client.httpGet(url, nil)
	if err != nil {
		return data, err
	}
	defer resp.Body.Close()
	switch resp.StatusCode {
	case 200:
		err = json.NewDecoder(resp.Body).Decode(&data)
		if err != nil {
			return data, err
		}
		return data, nil
	default:
		var errobj rdl.ResourceError
		contentBytes, err := io.ReadAll(resp.Body)
		if err != nil {
			return data, err
		}
		json.Unmarshal(contentBytes, &errobj)
		if errobj.Code == 0 {
			errobj.Code = resp.StatusCode
		}
		if errobj.Message == "" {
			errobj.Message = string(contentBytes)
		}
		return data, errobj
	}
}

func (client MSDClient) GetTransportPolicyRulesByDomain(domainName DomainName, matchingTag string) (*TransportPolicyRules, string, error) {
	var data *TransportPolicyRules
	headers := map[string]string{
		"If-None-Match": matchingTag,
	}
	url := client.URL + "/domain/" + fmt.Sprint(domainName) + "/transportpolicies"
	resp, err := client.httpGet(url, headers)
	if err != nil {
		return nil, "", err
	}
	defer resp.Body.Close()
	switch resp.StatusCode {
	case 200, 304:
		if 304 != resp.StatusCode {
			err = json.NewDecoder(resp.Body).Decode(&data)
			if err != nil {
				return nil, "", err
			}
		}
		tag := resp.Header.Get(rdl.FoldHttpHeaderName("ETag"))
		return data, tag, nil
	default:
		var errobj rdl.ResourceError
		contentBytes, err := io.ReadAll(resp.Body)
		if err != nil {
			return nil, "", err
		}
		json.Unmarshal(contentBytes, &errobj)
		if errobj.Code == 0 {
			errobj.Code = resp.StatusCode
		}
		if errobj.Message == "" {
			errobj.Message = string(contentBytes)
		}
		return nil, "", errobj
	}
}

func (client MSDClient) PutTransportPolicy(domainName DomainName, serviceName EntityName, auditRef string, resourceOwner string, payload *TransportPolicyRequest) (*TransportPolicyRules, error) {
	var data *TransportPolicyRules
	headers := map[string]string{
		"Athenz-Resource-Owner": resourceOwner,
		"Y-Audit-Ref":           auditRef,
	}
	url := client.URL + "/domain/" + fmt.Sprint(domainName) + "/service/" + fmt.Sprint(serviceName) + "/transportpolicy"
	contentBytes, err := json.Marshal(payload)
	if err != nil {
		return data, err
	}
	resp, err := client.httpPut(url, headers, contentBytes)
	if err != nil {
		return data, err
	}
	defer resp.Body.Close()
	switch resp.StatusCode {
	case 204, 200:
		if 204 != resp.StatusCode {
			err = json.NewDecoder(resp.Body).Decode(&data)
			if err != nil {
				return data, err
			}
		}
		return data, nil
	default:
		var errobj rdl.ResourceError
		contentBytes, err = io.ReadAll(resp.Body)
		if err != nil {
			return data, err
		}
		json.Unmarshal(contentBytes, &errobj)
		if errobj.Code == 0 {
			errobj.Code = resp.StatusCode
		}
		if errobj.Message == "" {
			errobj.Message = string(contentBytes)
		}
		return data, errobj
	}
}

func (client MSDClient) GetTransportPolicyRulesByService(domainName DomainName, serviceName EntityName, matchingTag string) (*TransportPolicyRules, string, error) {
	var data *TransportPolicyRules
	headers := map[string]string{
		"If-None-Match": matchingTag,
	}
	url := client.URL + "/domain/" + fmt.Sprint(domainName) + "/service/" + fmt.Sprint(serviceName) + "/transportpolicies"
	resp, err := client.httpGet(url, headers)
	if err != nil {
		return nil, "", err
	}
	defer resp.Body.Close()
	switch resp.StatusCode {
	case 200, 304:
		if 304 != resp.StatusCode {
			err = json.NewDecoder(resp.Body).Decode(&data)
			if err != nil {
				return nil, "", err
			}
		}
		tag := resp.Header.Get(rdl.FoldHttpHeaderName("ETag"))
		return data, tag, nil
	default:
		var errobj rdl.ResourceError
		contentBytes, err := io.ReadAll(resp.Body)
		if err != nil {
			return nil, "", err
		}
		json.Unmarshal(contentBytes, &errobj)
		if errobj.Code == 0 {
			errobj.Code = resp.StatusCode
		}
		if errobj.Message == "" {
			errobj.Message = string(contentBytes)
		}
		return nil, "", errobj
	}
}

func (client MSDClient) DeleteTransportPolicy(domainName DomainName, serviceName EntityName, id int64, auditRef string, resourceOwner string) error {
	headers := map[string]string{
		"Athenz-Resource-Owner": resourceOwner,
		"Y-Audit-Ref":           auditRef,
	}
	url := client.URL + "/domain/" + fmt.Sprint(domainName) + "/service/" + fmt.Sprint(serviceName) + "/transportpolicy/" + fmt.Sprint(id)
	resp, err := client.httpDelete(url, headers)
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	switch resp.StatusCode {
	case 204:
		return nil
	default:
		var errobj rdl.ResourceError
		contentBytes, err := io.ReadAll(resp.Body)
		if err != nil {
			return err
		}
		json.Unmarshal(contentBytes, &errobj)
		if errobj.Code == 0 {
			errobj.Code = resp.StatusCode
		}
		if errobj.Message == "" {
			errobj.Message = string(contentBytes)
		}
		return errobj
	}
}

func (client MSDClient) GetWorkloadsByService(domainName DomainName, serviceName EntityName, matchingTag string) (*Workloads, string, error) {
	var data *Workloads
	headers := map[string]string{
		"If-None-Match": matchingTag,
	}
	url := client.URL + "/domain/" + fmt.Sprint(domainName) + "/service/" + fmt.Sprint(serviceName) + "/workloads"
	resp, err := client.httpGet(url, headers)
	if err != nil {
		return nil, "", err
	}
	defer resp.Body.Close()
	switch resp.StatusCode {
	case 200, 304:
		if 304 != resp.StatusCode {
			err = json.NewDecoder(resp.Body).Decode(&data)
			if err != nil {
				return nil, "", err
			}
		}
		tag := resp.Header.Get(rdl.FoldHttpHeaderName("ETag"))
		return data, tag, nil
	default:
		var errobj rdl.ResourceError
		contentBytes, err := io.ReadAll(resp.Body)
		if err != nil {
			return nil, "", err
		}
		json.Unmarshal(contentBytes, &errobj)
		if errobj.Code == 0 {
			errobj.Code = resp.StatusCode
		}
		if errobj.Message == "" {
			errobj.Message = string(contentBytes)
		}
		return nil, "", errobj
	}
}

func (client MSDClient) GetWorkloadsByIP(ip string, matchingTag string) (*Workloads, string, error) {
	var data *Workloads
	headers := map[string]string{
		"If-None-Match": matchingTag,
	}
	url := client.URL + "/workloads/" + ip
	resp, err := client.httpGet(url, headers)
	if err != nil {
		return nil, "", err
	}
	defer resp.Body.Close()
	switch resp.StatusCode {
	case 200, 304:
		if 304 != resp.StatusCode {
			err = json.NewDecoder(resp.Body).Decode(&data)
			if err != nil {
				return nil, "", err
			}
		}
		tag := resp.Header.Get(rdl.FoldHttpHeaderName("ETag"))
		return data, tag, nil
	default:
		var errobj rdl.ResourceError
		contentBytes, err := io.ReadAll(resp.Body)
		if err != nil {
			return nil, "", err
		}
		json.Unmarshal(contentBytes, &errobj)
		if errobj.Code == 0 {
			errobj.Code = resp.StatusCode
		}
		if errobj.Message == "" {
			errobj.Message = string(contentBytes)
		}
		return nil, "", errobj
	}
}

func (client MSDClient) PutDynamicWorkload(domainName DomainName, serviceName EntityName, options *WorkloadOptions, resourceOwner string) error {
	headers := map[string]string{
		"Athenz-Resource-Owner": resourceOwner,
	}
	url := client.URL + "/domain/" + fmt.Sprint(domainName) + "/service/" + fmt.Sprint(serviceName) + "/workload/dynamic"
	contentBytes, err := json.Marshal(options)
	if err != nil {
		return err
	}
	resp, err := client.httpPut(url, headers, contentBytes)
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	switch resp.StatusCode {
	case 204:
		return nil
	default:
		var errobj rdl.ResourceError
		contentBytes, err = io.ReadAll(resp.Body)
		if err != nil {
			return err
		}
		json.Unmarshal(contentBytes, &errobj)
		if errobj.Code == 0 {
			errobj.Code = resp.StatusCode
		}
		if errobj.Message == "" {
			errobj.Message = string(contentBytes)
		}
		return errobj
	}
}

func (client MSDClient) DeleteDynamicWorkload(domainName DomainName, serviceName EntityName, instanceId PathElement, resourceOwner string) error {
	headers := map[string]string{
		"Athenz-Resource-Owner": resourceOwner,
	}
	url := client.URL + "/domain/" + fmt.Sprint(domainName) + "/service/" + fmt.Sprint(serviceName) + "/instanceId/" + fmt.Sprint(instanceId) + "/workload/dynamic"
	resp, err := client.httpDelete(url, headers)
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	switch resp.StatusCode {
	case 204:
		return nil
	default:
		var errobj rdl.ResourceError
		contentBytes, err := io.ReadAll(resp.Body)
		if err != nil {
			return err
		}
		json.Unmarshal(contentBytes, &errobj)
		if errobj.Code == 0 {
			errobj.Code = resp.StatusCode
		}
		if errobj.Message == "" {
			errobj.Message = string(contentBytes)
		}
		return errobj
	}
}

func (client MSDClient) PutStaticWorkload(domainName DomainName, serviceName EntityName, staticWorkload *StaticWorkload, resourceOwner string) error {
	headers := map[string]string{
		"Athenz-Resource-Owner": resourceOwner,
	}
	url := client.URL + "/domain/" + fmt.Sprint(domainName) + "/service/" + fmt.Sprint(serviceName) + "/workload/static"
	contentBytes, err := json.Marshal(staticWorkload)
	if err != nil {
		return err
	}
	resp, err := client.httpPut(url, headers, contentBytes)
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	switch resp.StatusCode {
	case 204:
		return nil
	default:
		var errobj rdl.ResourceError
		contentBytes, err = io.ReadAll(resp.Body)
		if err != nil {
			return err
		}
		json.Unmarshal(contentBytes, &errobj)
		if errobj.Code == 0 {
			errobj.Code = resp.StatusCode
		}
		if errobj.Message == "" {
			errobj.Message = string(contentBytes)
		}
		return errobj
	}
}

func (client MSDClient) DeleteStaticWorkload(domainName DomainName, serviceName EntityName, name StaticWorkloadName, resourceOwner string) error {
	headers := map[string]string{
		"Athenz-Resource-Owner": resourceOwner,
	}
	url := client.URL + "/domain/" + fmt.Sprint(domainName) + "/service/" + fmt.Sprint(serviceName) + "/name/" + fmt.Sprint(name) + "/workload/static"
	resp, err := client.httpDelete(url, headers)
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	switch resp.StatusCode {
	case 204:
		return nil
	default:
		var errobj rdl.ResourceError
		contentBytes, err := io.ReadAll(resp.Body)
		if err != nil {
			return err
		}
		json.Unmarshal(contentBytes, &errobj)
		if errobj.Code == 0 {
			errobj.Code = resp.StatusCode
		}
		if errobj.Message == "" {
			errobj.Message = string(contentBytes)
		}
		return errobj
	}
}

func (client MSDClient) GetStaticWorkloadServicesByType(serviceType EntityName, serviceValue EntityName) (*StaticWorkloadServices, error) {
	var data *StaticWorkloadServices
	url := client.URL + "/services/" + fmt.Sprint(serviceType) + encodeParams(encodeStringParam("value", string(serviceValue), ""))
	resp, err := client.httpGet(url, nil)
	if err != nil {
		return data, err
	}
	defer resp.Body.Close()
	switch resp.StatusCode {
	case 200, 304:
		if 304 != resp.StatusCode {
			err = json.NewDecoder(resp.Body).Decode(&data)
			if err != nil {
				return data, err
			}
		}
		return data, nil
	default:
		var errobj rdl.ResourceError
		contentBytes, err := io.ReadAll(resp.Body)
		if err != nil {
			return data, err
		}
		json.Unmarshal(contentBytes, &errobj)
		if errobj.Code == 0 {
			errobj.Code = resp.StatusCode
		}
		if errobj.Message == "" {
			errobj.Message = string(contentBytes)
		}
		return data, errobj
	}
}

func (client MSDClient) GetWorkloadsByDomain(domainName DomainName, matchingTag string) (*Workloads, string, error) {
	var data *Workloads
	headers := map[string]string{
		"If-None-Match": matchingTag,
	}
	url := client.URL + "/domain/" + fmt.Sprint(domainName) + "/workloads"
	resp, err := client.httpGet(url, headers)
	if err != nil {
		return nil, "", err
	}
	defer resp.Body.Close()
	switch resp.StatusCode {
	case 200, 304:
		if 304 != resp.StatusCode {
			err = json.NewDecoder(resp.Body).Decode(&data)
			if err != nil {
				return nil, "", err
			}
		}
		tag := resp.Header.Get(rdl.FoldHttpHeaderName("ETag"))
		return data, tag, nil
	default:
		var errobj rdl.ResourceError
		contentBytes, err := io.ReadAll(resp.Body)
		if err != nil {
			return nil, "", err
		}
		json.Unmarshal(contentBytes, &errobj)
		if errobj.Code == 0 {
			errobj.Code = resp.StatusCode
		}
		if errobj.Message == "" {
			errobj.Message = string(contentBytes)
		}
		return nil, "", errobj
	}
}

func (client MSDClient) GetWorkloadsByDomainAndService(request *BulkWorkloadRequest, matchingTag string) (*BulkWorkloadResponse, string, error) {
	var data *BulkWorkloadResponse
	headers := map[string]string{
		"If-None-Match": matchingTag,
	}
	url := client.URL + "/workloads"
	contentBytes, err := json.Marshal(request)
	if err != nil {
		return nil, "", err
	}
	resp, err := client.httpPost(url, headers, contentBytes)
	if err != nil {
		return nil, "", err
	}
	defer resp.Body.Close()
	switch resp.StatusCode {
	case 200, 304:
		if 304 != resp.StatusCode {
			err = json.NewDecoder(resp.Body).Decode(&data)
			if err != nil {
				return nil, "", err
			}
		}
		tag := resp.Header.Get(rdl.FoldHttpHeaderName("ETag"))
		return data, tag, nil
	default:
		var errobj rdl.ResourceError
		contentBytes, err = io.ReadAll(resp.Body)
		if err != nil {
			return nil, "", err
		}
		json.Unmarshal(contentBytes, &errobj)
		if errobj.Code == 0 {
			errobj.Code = resp.StatusCode
		}
		if errobj.Message == "" {
			errobj.Message = string(contentBytes)
		}
		return nil, "", errobj
	}
}

func (client MSDClient) PutCompositeInstance(domainName DomainName, serviceName EntityName, instance *CompositeInstance, resourceOwner string) error {
	headers := map[string]string{
		"Athenz-Resource-Owner": resourceOwner,
	}
	url := client.URL + "/domain/" + fmt.Sprint(domainName) + "/service/" + fmt.Sprint(serviceName) + "/workload/discover/instance"
	contentBytes, err := json.Marshal(instance)
	if err != nil {
		return err
	}
	resp, err := client.httpPut(url, headers, contentBytes)
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	switch resp.StatusCode {
	case 204:
		return nil
	default:
		var errobj rdl.ResourceError
		contentBytes, err = io.ReadAll(resp.Body)
		if err != nil {
			return err
		}
		json.Unmarshal(contentBytes, &errobj)
		if errobj.Code == 0 {
			errobj.Code = resp.StatusCode
		}
		if errobj.Message == "" {
			errobj.Message = string(contentBytes)
		}
		return errobj
	}
}

func (client MSDClient) DeleteCompositeInstance(domainName DomainName, serviceName EntityName, instance SimpleName, resourceOwner string) error {
	headers := map[string]string{
		"Athenz-Resource-Owner": resourceOwner,
	}
	url := client.URL + "/domain/" + fmt.Sprint(domainName) + "/service/" + fmt.Sprint(serviceName) + "/workload/discover/instance/" + fmt.Sprint(instance)
	resp, err := client.httpDelete(url, headers)
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	switch resp.StatusCode {
	case 204:
		return nil
	default:
		var errobj rdl.ResourceError
		contentBytes, err := io.ReadAll(resp.Body)
		if err != nil {
			return err
		}
		json.Unmarshal(contentBytes, &errobj)
		if errobj.Code == 0 {
			errobj.Code = resp.StatusCode
		}
		if errobj.Message == "" {
			errobj.Message = string(contentBytes)
		}
		return errobj
	}
}

func (client MSDClient) ResetWorkloadCacheCount(domainName DomainName, serviceName EntityName) error {
	url := client.URL + "/domain/" + fmt.Sprint(domainName) + "/service/" + fmt.Sprint(serviceName) + "/workload/count/cache"
	resp, err := client.httpDelete(url, nil)
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	switch resp.StatusCode {
	case 204:
		return nil
	default:
		var errobj rdl.ResourceError
		contentBytes, err := io.ReadAll(resp.Body)
		if err != nil {
			return err
		}
		json.Unmarshal(contentBytes, &errobj)
		if errobj.Code == 0 {
			errobj.Code = resp.StatusCode
		}
		if errobj.Message == "" {
			errobj.Message = string(contentBytes)
		}
		return errobj
	}
}

func (client MSDClient) GetWorkloadCount(domainName DomainName, serviceName EntityName) (*WorkloadCount, error) {
	var data *WorkloadCount
	url := client.URL + "/domain/" + fmt.Sprint(domainName) + "/service/" + fmt.Sprint(serviceName) + "/workload/count"
	resp, err := client.httpGet(url, nil)
	if err != nil {
		return data, err
	}
	defer resp.Body.Close()
	switch resp.StatusCode {
	case 200:
		err = json.NewDecoder(resp.Body).Decode(&data)
		if err != nil {
			return data, err
		}
		return data, nil
	default:
		var errobj rdl.ResourceError
		contentBytes, err := io.ReadAll(resp.Body)
		if err != nil {
			return data, err
		}
		json.Unmarshal(contentBytes, &errobj)
		if errobj.Code == 0 {
			errobj.Code = resp.StatusCode
		}
		if errobj.Message == "" {
			errobj.Message = string(contentBytes)
		}
		return data, errobj
	}
}

func (client MSDClient) EvaluateNetworkPolicyChange(detail *NetworkPolicyChangeImpactRequest) (*NetworkPolicyChangeImpactResponse, error) {
	var data *NetworkPolicyChangeImpactResponse
	url := client.URL + "/transportpolicy/evaluatenetworkpolicychange"
	contentBytes, err := json.Marshal(detail)
	if err != nil {
		return data, err
	}
	resp, err := client.httpPost(url, nil, contentBytes)
	if err != nil {
		return data, err
	}
	defer resp.Body.Close()
	switch resp.StatusCode {
	case 200:
		err = json.NewDecoder(resp.Body).Decode(&data)
		if err != nil {
			return data, err
		}
		return data, nil
	default:
		var errobj rdl.ResourceError
		contentBytes, err = io.ReadAll(resp.Body)
		if err != nil {
			return data, err
		}
		json.Unmarshal(contentBytes, &errobj)
		if errobj.Code == 0 {
			errobj.Code = resp.StatusCode
		}
		if errobj.Message == "" {
			errobj.Message = string(contentBytes)
		}
		return data, errobj
	}
}

func (client MSDClient) PostKubernetesNetworkPolicyRequest(domainName DomainName, serviceName EntityName, request *KubernetesNetworkPolicyRequest, matchingTag string) (*KubernetesNetworkPolicyResponse, string, error) {
	var data *KubernetesNetworkPolicyResponse
	headers := map[string]string{
		"If-None-Match": matchingTag,
	}
	url := client.URL + "/domain/" + fmt.Sprint(domainName) + "/service/" + fmt.Sprint(serviceName) + "/kubernetesnetworkpolicy"
	contentBytes, err := json.Marshal(request)
	if err != nil {
		return nil, "", err
	}
	resp, err := client.httpPost(url, headers, contentBytes)
	if err != nil {
		return nil, "", err
	}
	defer resp.Body.Close()
	switch resp.StatusCode {
	case 200, 304:
		if 304 != resp.StatusCode {
			err = json.NewDecoder(resp.Body).Decode(&data)
			if err != nil {
				return nil, "", err
			}
		}
		tag := resp.Header.Get(rdl.FoldHttpHeaderName("ETag"))
		return data, tag, nil
	default:
		var errobj rdl.ResourceError
		contentBytes, err = io.ReadAll(resp.Body)
		if err != nil {
			return nil, "", err
		}
		json.Unmarshal(contentBytes, &errobj)
		if errobj.Code == 0 {
			errobj.Code = resp.StatusCode
		}
		if errobj.Message == "" {
			errobj.Message = string(contentBytes)
		}
		return nil, "", errobj
	}
}

func (client MSDClient) GetRdlSchema() (*rdl.Schema, error) {
	var data *rdl.Schema
	url := client.URL + "/schema"
	resp, err := client.httpGet(url, nil)
	if err != nil {
		return data, err
	}
	defer resp.Body.Close()
	switch resp.StatusCode {
	case 200:
		err = json.NewDecoder(resp.Body).Decode(&data)
		if err != nil {
			return data, err
		}
		return data, nil
	default:
		var errobj rdl.ResourceError
		contentBytes, err := io.ReadAll(resp.Body)
		if err != nil {
			return data, err
		}
		json.Unmarshal(contentBytes, &errobj)
		if errobj.Code == 0 {
			errobj.Code = resp.StatusCode
		}
		if errobj.Message == "" {
			errobj.Message = string(contentBytes)
		}
		return data, errobj
	}
}
