func getEscape(s string) string {
	return escape(s, encodePathSegment)
}
getEscape is a custom implementation of url.PathEscape.
package rubrikcdm
import (
	"bytes"
	"crypto/tls"
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"net"
	"net/http"
	"os"
	"reflect"
	"sort"
	"time"
)
type encoding int
const (
	encodePath encoding = 1 + iota
	encodePathSegment
	encodeQueryComponent
)
type Credentials struct {
	NodeIP   string
	Username string
	Password string
	APIToken string
}
func Connect(nodeIP, username, password string, apiToken ...string) *Credentials {
	client := &Credentials{
		NodeIP:   nodeIP,
		Username: username,
		Password: password,
	}
	return client
}
func ConnectAPIToken(nodeIP, apiToken string) *Credentials {
	client := &Credentials{
		NodeIP:   nodeIP,
		APIToken: apiToken,
	}
	return client
}
func ConnectEnv() (*Credentials, error) {
	nodeIP, ok := os.LookupEnv("rubrik_cdm_node_ip")
	if ok != true {
		return nil, errors.New("The `rubrik_cdm_node_ip` environment variable is not present")
	}
	apiTokenFound := true
	apiToken, ok := os.LookupEnv("rubrik_cdm_token")
	if ok != true {
		apiTokenFound = false
	}
	var client *Credentials
	if apiTokenFound == false {
		username, ok := os.LookupEnv("rubrik_cdm_username")
		if ok != true {
			return nil, errors.New("The `rubrik_cdm_username` or `rubrik_cdm_token` environment variable is not present")
		}
		password, ok := os.LookupEnv("rubrik_cdm_password")
		if ok != true {
			return nil, errors.New("The `rubrik_cdm_password` or `rubrik_cdm_token` environment variable is not present")
		}
		client = &Credentials{
			NodeIP:   nodeIP,
			Username: username,
			Password: password,
		}
	} else {
		client = &Credentials{
			NodeIP:   nodeIP,
			APIToken: apiToken,
		}
	}
	return client, nil
}
func (c *Credentials) commonAPI(callType, apiVersion, apiEndpoint string, config interface{}, timeout int) (interface{}, error) {
	if apiVersionValidation(apiVersion) == false {
		return nil, errors.New("Enter a valid API version")
	}
	if endpointValidation(apiEndpoint) == "errorStart" {
		return nil, errors.New("The API Endpoint should begin with '/' (ex: /cluster/me)")
	} else if endpointValidation(apiEndpoint) == "errorEnd" {
		return nil, errors.New("The API Endpoint should not end with '/' (ex. /cluster/me)")
	}
	tr := &http.Transport{
		TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
	}
	client := &http.Client{
		Transport: tr,
		Timeout:   time.Second * time.Duration(timeout),
	}
	requestURL := fmt.Sprintf("https://%s/api/%s%s", c.NodeIP, apiVersion, apiEndpoint)
	var request *http.Request
	switch callType {
	case "GET":
		request, _ = http.NewRequest(callType, getEscape(requestURL), nil)
	case "POST":
		convertedConfig, _ := json.Marshal(config)
		request, _ = http.NewRequest(callType, requestURL, bytes.NewBuffer(convertedConfig))
	case "PATCH":
		convertedConfig, _ := json.Marshal(config)
		request, _ = http.NewRequest(callType, requestURL, bytes.NewBuffer(convertedConfig))
	case "DELETE":
		request, _ = http.NewRequest(callType, requestURL, nil)
	case "JOB_STATUS":
		requestURL = config.(string)
		request, _ = http.NewRequest("GET", requestURL, nil)
	}
	if len(c.Username) != 0 {
		request.SetBasicAuth(c.Username, c.Password)
	} else {
		request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", c.APIToken))
	}
	request.Header.Set("Content-Type", "application/json")
	request.Header.Set("Accept", "application/json")
	request.Header.Set("User-Agent", "Rubrik Go SDK v1.0.2")
	request.Close = true
	apiRequest, err := client.Do(request)
	if err, ok := err.(net.Error); ok && err.Timeout() {
		return nil, errors.New("Unable to establish a connection to the Rubrik cluster")
	} else if err != nil {
		return nil, err
	}
	defer apiRequest.Body.Close()
	body, err := ioutil.ReadAll(apiRequest.Body)
	apiResponse := []byte(body)
	var convertedAPIResponse interface{}
	if err := json.Unmarshal(apiResponse, &convertedAPIResponse); err != nil {
		if apiRequest.StatusCode == 204 {
			convertedAPIResponse = map[string]interface{}{}
			convertedAPIResponse.(map[string]interface{})["statusCode"] = apiRequest.StatusCode
		} else if apiRequest.StatusCode != 200 {
			return nil, fmt.Errorf("%s", apiRequest.Status)
		}
	}
	if reflect.TypeOf(convertedAPIResponse).Kind() == reflect.Slice {
		return convertedAPIResponse, nil
	}
	if _, ok := convertedAPIResponse.(map[string]interface{})["errorType"]; ok {
		return nil, fmt.Errorf("%s", convertedAPIResponse.(map[string]interface{})["message"])
	}
	if _, ok := convertedAPIResponse.(map[string]interface{})["message"]; ok {
		if _, ok := convertedAPIResponse.(map[string]interface{})["setupEncryptionAtRest"]; ok {
			return convertedAPIResponse, nil
		}
		return nil, fmt.Errorf("%s", convertedAPIResponse.(map[string]interface{})["message"])
	}
	return convertedAPIResponse, nil
}
func apiVersionValidation(apiVersion string) bool {
	validAPIVersions := []string{"v1", "v2", "internal"}
	for _, version := range validAPIVersions {
		if version == apiVersion {
			return true
		}
	}
	return false
}
func endpointValidation(apiEndpoint string) string {
	if string(apiEndpoint[0]) != "/" {
		return "errorStart"
	} else if string(apiEndpoint[len(apiEndpoint)-1]) == "/" {
		if string(apiEndpoint[len(apiEndpoint)-2]) != "=" {  
			return "errorEnd"
		}
	}
	return "success"
}
func httpTimeout(timeout []int) int {
	if len(timeout) == 0 {
		return int(15)  
	}
	return int(timeout[0])  
}
func apiToken(apiToken []string) string {
	if len(apiToken) == 0 {
		return ""  
	}
	return apiToken[0]  
}