/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package commands

import (
	"bufio"
	"bytes"
	"errors"
	"fmt"
	"reflect"
	"strconv"
	"strings"

	"github.com/apache/incubator-openwhisk-cli/wski18n"
	"github.com/apache/incubator-openwhisk-client-go/whisk"

	"encoding/json"
	"github.com/fatih/color"
	"github.com/ghodss/yaml"
	"github.com/spf13/cobra"
	"regexp"
)

const (
	yamlFileExtension = "yaml"
	ymlFileExtension  = "yml"

	formatOptionYaml = "yaml"
	formatOptionJson = "json"

	pathParamRegex        = `\/\{([^\/]+)\}\/|\/\{([^\/]+)\}$|\{([^\/]+)}\/`
	pathSegmentParamRegex = `^\/\{([^\/]+)\}\/$`
)

var apiCmd = &cobra.Command{
	Use:   "api",
	Short: wski18n.T("work with APIs"),
}

var fmtString = "%-30s %7s %20s  %s\n"

// When set, this overrides the default authkey based api context id
var ContextId string

// When set, this overrides the default access token used to authenticate with the api gw
var ApiGwAccessToken string

func IsValidApiVerb(verb string) (error, bool) {
	// Is the API verb valid?
	if _, ok := whisk.ApiVerbs[strings.ToUpper(verb)]; !ok {
		whisk.Debug(whisk.DbgError, "Invalid API verb: '%s'\n", verb)
		errMsg := wski18n.T("'{{.verb}}' is not a valid API verb.  Valid values are: {{.verbs}}",
			map[string]interface{}{
				"verb":  verb,
				"verbs": reflect.ValueOf(whisk.ApiVerbs).MapKeys()})
		whiskErr := whisk.MakeWskError(errors.New(errMsg), whisk.EXIT_CODE_ERR_GENERAL,
			whisk.DISPLAY_MSG, whisk.DISPLAY_USAGE)
		return whiskErr, false
	}
	return nil, true
}

func hasPathPrefix(path string) (error, bool) {
	if !strings.HasPrefix(path, "/") {
		whisk.Debug(whisk.DbgError, "path does not begin with '/': '%s'\n", path)
		errMsg := wski18n.T("'{{.path}}' must begin with '/'.",
			map[string]interface{}{
				"path": path,
			})
		whiskErr := whisk.MakeWskError(errors.New(errMsg), whisk.EXIT_CODE_ERR_GENERAL,
			whisk.DISPLAY_MSG, whisk.DISPLAY_USAGE)
		return whiskErr, false
	}
	return nil, true
}

func isValidBasepath(basepath string) (error, bool) {
	if whiskerr, ok := hasPathPrefix(basepath); !ok {
		return whiskerr, false
	}
	return nil, true
}

func isValidRelpath(relpath string) (error, bool) {
	if whiskerr, ok := hasPathPrefix(relpath); !ok {
		return whiskerr, false
	}
	return nil, true
}

func getPathParameterNames(path string) ([]string, error) {
	var pathParameters []string

	regexObj, err := regexp.Compile(pathSegmentParamRegex)
	if err != nil {
		whisk.Debug(whisk.DbgError, "Failed to match path '%s' to regular expressions `%s`\n", path, pathSegmentParamRegex)
	} else {
		segments := strings.Split(path, "/")
		for _, segment := range segments {
			segment = fmt.Sprintf("/%s/", segment)
			matchedItems := regexObj.FindAllStringSubmatch(segment, -1)
			for _, matchedParam := range matchedItems {
				for idx, paramName := range matchedParam {
					whisk.Debug(whisk.DbgInfo, "Path parameter submatch '%v'; idx %v\n", paramName, idx)
					if idx > 0 && len(paramName) > 0 {
						pathParameters = append(pathParameters, paramName)
					}
				}
			}
		}
	}

	return pathParameters, err
}

func hasPathParameters(path string) (bool, error) {
	pathParams, err := getPathParameterNames(path)
	return len(pathParams) > 0, err
}

func isBasepathParameterized(basepath string) (error, bool) {
	hasParams, err := hasPathParameters(basepath)
	if hasParams || err != nil {
		errMsg := wski18n.T("The base path '{{.path}}' cannot have parameters. Only the relative path supports path parameters.",
			map[string]interface{}{"path": basepath})
		whiskErr := whisk.MakeWskError(errors.New(errMsg), whisk.EXIT_CODE_ERR_GENERAL,
			whisk.DISPLAY_MSG, whisk.DISPLAY_USAGE)
		return whiskErr, false
	}
	return nil, true
}

/*
 * Pull the managedUrl (external API URL) from the API configuration
 */
func getManagedUrl(api *whisk.RetApi, relpath string, operation string) (url string) {
	baseUrl := strings.TrimSuffix(api.BaseUrl, "/")
	whisk.Debug(whisk.DbgInfo, "getManagedUrl: baseUrl = '%s', relpath = '%s', operation = '%s'\n", baseUrl, relpath, operation)
	for path := range api.Swagger.Paths {
		whisk.Debug(whisk.DbgInfo, "getManagedUrl: comparing api relpath: '%s'\n", path)
		if path == relpath {
			whisk.Debug(whisk.DbgInfo, "getManagedUrl: relpath matches '%s'\n", relpath)
			for op := range api.Swagger.Paths[path].MakeOperationMap() {
				whisk.Debug(whisk.DbgInfo, "getManagedUrl: comparing operation: '%s'\n", op)
				if strings.ToLower(op) == strings.ToLower(operation) {
					whisk.Debug(whisk.DbgInfo, "getManagedUrl: operation matches: '%s'\n", operation)
					url = baseUrl + path
				}
			}
		}
	}
	return url
}

//////////////
// Commands //
//////////////
var apiCreateCmd = &cobra.Command{
	Use:           "create ([BASE_PATH] API_PATH API_VERB ACTION] | --config-file CFG_FILE) ",
	Short:         wski18n.T("create a new API"),
	SilenceUsage:  true,
	SilenceErrors: true,
	PreRunE:       SetupClientConfig,
	RunE: func(cmd *cobra.Command, args []string) error {
		var api *whisk.Api
		var err error
		var qname = new(QualifiedName)
		var action *whisk.Action
		var webactionSecret interface{}

		if len(args) == 0 && Flags.api.configfile == "" {
			whisk.Debug(whisk.DbgError, "No swagger file and no arguments\n")
			errMsg := wski18n.T("Invalid argument(s). Specify a swagger file or specify an API base path with an API path, an API verb, and an action name.")
			whiskErr := whisk.MakeWskError(errors.New(errMsg), whisk.EXIT_CODE_ERR_GENERAL,
				whisk.DISPLAY_MSG, whisk.DISPLAY_USAGE)
			return whiskErr
		} else if len(args) == 0 && Flags.api.configfile != "" {
			api, err = parseSwaggerApi(Flags.api.configfile, Client.Config.Namespace)
			if err != nil {
				whisk.Debug(whisk.DbgError, "parseSwaggerApi() error: %s\n", err)
				errMsg := wski18n.T("Unable to parse swagger file: {{.err}}", map[string]interface{}{"err": err})
				whiskErr := whisk.MakeWskErrorFromWskError(errors.New(errMsg), err, whisk.EXIT_CODE_ERR_GENERAL,
					whisk.DISPLAY_MSG, whisk.DISPLAY_USAGE)
				return whiskErr
			}
		} else {
			if whiskErr := CheckArgs(args, 3, 4, "Api create",
				wski18n.T("Specify a swagger file or specify an API base path with an API path, an API verb, and an action name.")); whiskErr != nil {
				return whiskErr
			}
			api, qname, err = parseApi(cmd, args)
			if err != nil {
				whisk.Debug(whisk.DbgError, "parseApi(%s, %s) error: %s\n", cmd, args, err)
				errMsg := wski18n.T("Unable to parse api command arguments: {{.err}}",
					map[string]interface{}{"err": err})
				whiskErr := whisk.MakeWskErrorFromWskError(errors.New(errMsg), err, whisk.EXIT_CODE_ERR_GENERAL,
					whisk.DISPLAY_MSG, whisk.DISPLAY_USAGE)
				return whiskErr
			}

			// Confirm that the specified action is a web-action
			action, err = isWebAction(Client, *qname)
			if err != nil {
				whisk.Debug(whisk.DbgError, "isWebAction(%v) is false: %s\n", qname, err)
				whiskErr := whisk.MakeWskError(err, whisk.EXIT_CODE_ERR_GENERAL, whisk.DISPLAY_MSG, whisk.DISPLAY_USAGE)
				return whiskErr
			}

			if webactionSecret = action.Annotations.GetValue(WEB_SECURE_ANNOT); webactionSecret != nil {
				whisk.Debug(whisk.DbgInfo, "web action is secured\n")
			}
		}

		apiCreateReq := new(whisk.ApiCreateRequest)
		apiCreateReq.ApiDoc = api

		apiCreateReqOptions := new(whisk.ApiCreateRequestOptions)
		if apiCreateReqOptions.SpaceGuid, err = getUserContextId(); err != nil {
			return err
		}
		if apiCreateReqOptions.AccessToken, err = getAccessToken(); err != nil {
			return err
		}
		apiCreateReqOptions.ResponseType = Flags.api.resptype

		if webactionSecret != nil {
			apiCreateReq.ApiDoc.Action.SecureKey = webactionSecret
		}

		whisk.Debug(whisk.DbgInfo, "AccessToken: %s\nSpaceGuid: %s\nResponseType: %s",
			apiCreateReqOptions.AccessToken, apiCreateReqOptions.SpaceGuid, apiCreateReqOptions.ResponseType)

		retApi, _, err := Client.Apis.Insert(apiCreateReq, apiCreateReqOptions, whisk.DoNotOverwrite)
		if err != nil {
			whisk.Debug(whisk.DbgError, "Client.Apis.Insert(%#v, false) error: %s\n", api, err)
			errMsg := wski18n.T("Unable to create API: {{.err}}", map[string]interface{}{"err": err})
			whiskErr := whisk.MakeWskError(errors.New(errMsg), whisk.EXIT_CODE_ERR_GENERAL,
				whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE)
			return whiskErr
		}

		if api.Swagger == "" {
			baseUrl := retApi.BaseUrl
			fmt.Fprintf(color.Output,
				wski18n.T("{{.ok}} created API {{.path}} {{.verb}} for action {{.name}}\n{{.fullpath}}\n",
					map[string]interface{}{
						"ok":       color.GreenString("ok:"),
						"path":     strings.TrimSuffix(api.GatewayBasePath, "/") + api.GatewayRelPath,
						"verb":     api.GatewayMethod,
						"name":     boldString("/" + api.Action.Namespace + "/" + api.Action.Name),
						"fullpath": strings.TrimSuffix(baseUrl, "/") + api.GatewayRelPath,
					}))
		} else {
			whisk.Debug(whisk.DbgInfo, "Processing swagger based create API response\n")
			baseUrl := retApi.BaseUrl
			for path := range retApi.Swagger.Paths {
				managedUrl := strings.TrimSuffix(baseUrl, "/") + path
				whisk.Debug(whisk.DbgInfo, "Managed path: '%s'\n", managedUrl)
				for op, opv := range retApi.Swagger.Paths[path].MakeOperationMap() {
					whisk.Debug(whisk.DbgInfo, "Path operation: '%s'\n", op)
					var fqActionName string
					if opv.XOpenWhisk == nil {
						fqActionName = ""
					} else if len(opv.XOpenWhisk.Package) > 0 {
						fqActionName = "/" + opv.XOpenWhisk.Namespace + "/" + opv.XOpenWhisk.Package + "/" + opv.XOpenWhisk.ActionName
					} else {
						fqActionName = "/" + opv.XOpenWhisk.Namespace + "/" + opv.XOpenWhisk.ActionName
					}

					whisk.Debug(whisk.DbgInfo, "baseUrl '%s'  Path '%s'  Path obj %+v\n", baseUrl, path, opv)
					if len(fqActionName) > 0 {
						fmt.Fprintf(color.Output,
							wski18n.T("{{.ok}} created API {{.path}} {{.verb}} for action {{.name}}\n{{.fullpath}}\n",
								map[string]interface{}{
									"ok":       color.GreenString("ok:"),
									"path":     strings.TrimSuffix(retApi.Swagger.BasePath, "/") + path,
									"verb":     op,
									"name":     boldString(fqActionName),
									"fullpath": managedUrl,
								}))
					} else {
						fmt.Fprintf(color.Output,
							wski18n.T("{{.ok}} created API {{.path}} {{.verb}}\n{{.fullpath}}\n",
								map[string]interface{}{
									"ok":       color.GreenString("ok:"),
									"path":     strings.TrimSuffix(retApi.Swagger.BasePath, "/") + path,
									"verb":     op,
									"fullpath": managedUrl,
								}))
					}
				}
			}
		}

		return nil
	},
}

var apiGetCmd = &cobra.Command{
	Use:           "get BASE_PATH | API_NAME",
	Short:         wski18n.T("get API details"),
	SilenceUsage:  true,
	SilenceErrors: true,
	PreRunE:       SetupClientConfig,
	RunE: func(cmd *cobra.Command, args []string) error {
		var err error
		var isBasePathArg bool = true

		if whiskErr := CheckArgs(args, 1, 1, "Api get",
			wski18n.T("An API base path or API name is required.")); whiskErr != nil {
			return whiskErr
		}

		if cmd.LocalFlags().Changed("format") &&
			strings.ToLower(Flags.common.format) != formatOptionYaml &&
			strings.ToLower(Flags.common.format) != formatOptionJson {
			errMsg := wski18n.T("Invalid format type: {{.type}}", map[string]interface{}{"type": Flags.common.format})
			whiskErr := whisk.MakeWskError(errors.New(errMsg), whisk.EXIT_CODE_ERR_GENERAL,
				whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE)
			return whiskErr
		}

		apiGetReq := new(whisk.ApiGetRequest)
		apiGetReqOptions := new(whisk.ApiGetRequestOptions)
		apiGetReqOptions.ApiBasePath = args[0]
		if apiGetReqOptions.SpaceGuid, err = getUserContextId(); err != nil {
			return err
		}
		if apiGetReqOptions.AccessToken, err = getAccessToken(); err != nil {
			return err
		}

		retApi, _, err := Client.Apis.Get(apiGetReq, apiGetReqOptions)
		if err != nil {
			whisk.Debug(whisk.DbgError, "Client.Apis.Get(%#v, %#v) error: %s\n", apiGetReq, apiGetReqOptions, err)
			errMsg := wski18n.T("Unable to get API '{{.name}}': {{.err}}", map[string]interface{}{"name": args[0], "err": err})
			whiskErr := whisk.MakeWskError(errors.New(errMsg), whisk.EXIT_CODE_ERR_GENERAL,
				whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE)
			return whiskErr
		}
		whisk.Debug(whisk.DbgInfo, "Client.Apis.Get returned: %#v\n", retApi)

		var displayResult interface{} = nil
		if Flags.common.detail {
			if retApi.Apis != nil && len(retApi.Apis) > 0 &&
				retApi.Apis[0].ApiValue != nil {
				displayResult = retApi.Apis[0].ApiValue
			} else {
				whisk.Debug(whisk.DbgError, "No result object returned\n")
			}
		} else {
			if retApi.Apis != nil && len(retApi.Apis) > 0 &&
				retApi.Apis[0].ApiValue != nil &&
				retApi.Apis[0].ApiValue.Swagger != nil {
				displayResult = retApi.Apis[0].ApiValue.Swagger
			} else {
				whisk.Debug(whisk.DbgError, "No swagger returned\n")
			}
		}
		if displayResult == nil {
			var errMsg string
			if isBasePathArg {
				errMsg = wski18n.T("API does not exist for basepath {{.basepath}}",
					map[string]interface{}{"basepath": args[0]})
			} else {
				errMsg = wski18n.T("API does not exist for API name {{.apiname}}",
					map[string]interface{}{"apiname": args[0]})
			}

			whiskErr := whisk.MakeWskError(errors.New(errMsg), whisk.EXIT_CODE_ERR_GENERAL,
				whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE)
			return whiskErr
		}

		if cmd.LocalFlags().Changed("format") && strings.ToLower(Flags.common.format) == formatOptionYaml {
			var jsonOutputBuffer bytes.Buffer
			var jsonOutputWriter = bufio.NewWriter(&jsonOutputBuffer)
			printJSON(displayResult, jsonOutputWriter)
			jsonOutputWriter.Flush()
			yamlbytes, err := yaml.JSONToYAML(jsonOutputBuffer.Bytes())
			if err != nil {
				whisk.Debug(whisk.DbgError, "yaml.JSONToYAML() error: %s\n", err)
				errMsg := wski18n.T("Unable to convert API into YAML: {{.err}}", map[string]interface{}{"err": err})
				whiskErr := whisk.MakeWskError(errors.New(errMsg), whisk.EXIT_CODE_ERR_GENERAL,
					whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE)
				return whiskErr
			}
			fmt.Println(string(yamlbytes))
		} else {
			printJSON(displayResult)
		}

		return nil
	},
}

var apiDeleteCmd = &cobra.Command{
	Use:           "delete BASE_PATH | API_NAME [API_PATH [API_VERB]]",
	Short:         wski18n.T("delete an API"),
	SilenceUsage:  true,
	SilenceErrors: true,
	PreRunE:       SetupClientConfig,
	RunE: func(cmd *cobra.Command, args []string) error {
		var err error

		if whiskErr := CheckArgs(args, 1, 3, "Api delete",
			wski18n.T("An API base path or API name is required.  An optional API relative path and operation may also be provided.")); whiskErr != nil {
			return whiskErr
		}

		apiDeleteReq := new(whisk.ApiDeleteRequest)
		apiDeleteReqOptions := new(whisk.ApiDeleteRequestOptions)
		if apiDeleteReqOptions.SpaceGuid, err = getUserContextId(); err != nil {
			return err
		}
		if apiDeleteReqOptions.AccessToken, err = getAccessToken(); err != nil {
			return err
		}

		// Is the argument a basepath (must start with /) or an API name
		if _, ok := isValidBasepath(args[0]); !ok {
			whisk.Debug(whisk.DbgInfo, "Treating '%s' as an API name; as it does not begin with '/'\n", args[0])
			apiDeleteReqOptions.ApiBasePath = args[0]
		} else {
			apiDeleteReqOptions.ApiBasePath = args[0]
		}

		if len(args) > 1 {
			// Is the API path valid?
			if whiskErr, ok := isValidRelpath(args[1]); !ok {
				return whiskErr
			}
			apiDeleteReqOptions.ApiRelPath = args[1]
		}
		if len(args) > 2 {
			// Is the API verb valid?
			if whiskErr, ok := IsValidApiVerb(args[2]); !ok {
				return whiskErr
			}
			apiDeleteReqOptions.ApiVerb = strings.ToUpper(args[2])
		}

		_, err = Client.Apis.Delete(apiDeleteReq, apiDeleteReqOptions)
		if err != nil {
			whisk.Debug(whisk.DbgError, "Client.Apis.Delete(%#v, %#v) error: %s\n", apiDeleteReq, apiDeleteReqOptions, err)
			errMsg := wski18n.T("Unable to delete API: {{.err}}", map[string]interface{}{"err": err})
			whiskErr := whisk.MakeWskError(errors.New(errMsg), whisk.EXIT_CODE_ERR_GENERAL,
				whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE)
			return whiskErr
		}

		if len(args) == 1 {
			fmt.Fprintf(color.Output,
				wski18n.T("{{.ok}} deleted API {{.basepath}}\n",
					map[string]interface{}{
						"ok":       color.GreenString("ok:"),
						"basepath": apiDeleteReqOptions.ApiBasePath,
					}))
		} else if len(args) == 2 {
			fmt.Fprintf(color.Output,
				wski18n.T("{{.ok}} deleted {{.path}} from {{.basepath}}\n",
					map[string]interface{}{
						"ok":       color.GreenString("ok:"),
						"path":     apiDeleteReqOptions.ApiRelPath,
						"basepath": apiDeleteReqOptions.ApiBasePath,
					}))
		} else {
			fmt.Fprintf(color.Output,
				wski18n.T("{{.ok}} deleted {{.path}} {{.verb}} from {{.basepath}}\n",
					map[string]interface{}{
						"ok":       color.GreenString("ok:"),
						"path":     apiDeleteReqOptions.ApiRelPath,
						"verb":     apiDeleteReqOptions.ApiVerb,
						"basepath": apiDeleteReqOptions.ApiBasePath,
					}))
		}

		return nil
	},
}

var apiListCmd = &cobra.Command{
	Use:           "list [[BASE_PATH | API_NAME] [API_PATH [API_VERB]]",
	Short:         wski18n.T("list APIs"),
	SilenceUsage:  true,
	SilenceErrors: true,
	PreRunE:       SetupClientConfig,
	RunE: func(cmd *cobra.Command, args []string) error {
		var err error
		var retApiList *whisk.ApiListResponse
		var retApi *whisk.ApiGetResponse
		var retApiArray *whisk.RetApiArray
		var apiPath string
		var apiVerb string
		var orderFilteredList []whisk.ApiFilteredList
		var orderFilteredRow []whisk.ApiFilteredRow

		if whiskErr := CheckArgs(args, 0, 3, "Api list",
			wski18n.T("Optional parameters are: API base path (or API name), API relative path and operation.")); whiskErr != nil {
			return whiskErr
		}

		if len(args) == 0 {
			// List API request query parameters
			apiListReqOptions := new(whisk.ApiListRequestOptions)
			apiListReqOptions.Limit = Flags.common.limit
			apiListReqOptions.Skip = Flags.common.skip
			if apiListReqOptions.SpaceGuid, err = getUserContextId(); err != nil {
				return err
			}
			if apiListReqOptions.AccessToken, err = getAccessToken(); err != nil {
				return err
			}

			retApiList, _, err = Client.Apis.List(apiListReqOptions)
			if err != nil {
				whisk.Debug(whisk.DbgError, "Client.Apis.List(%#v) error: %s\n", apiListReqOptions, err)
				errMsg := wski18n.T("Unable to obtain the API list: {{.err}}", map[string]interface{}{"err": err})
				whiskErr := whisk.MakeWskError(errors.New(errMsg), whisk.EXIT_CODE_ERR_GENERAL,
					whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE)
				return whiskErr
			}
			whisk.Debug(whisk.DbgInfo, "Client.Apis.List returned: %#v (%+v)\n", retApiList, retApiList)
			// Cast to a common type to allow for code to print out apilist response or apiget response
			retApiArray = (*whisk.RetApiArray)(retApiList)
		} else {
			// Get API request body
			apiGetReq := new(whisk.ApiGetRequest)
			apiGetReq.Namespace = Client.Config.Namespace
			// Get API request options
			apiGetReqOptions := new(whisk.ApiGetRequestOptions)
			if apiGetReqOptions.SpaceGuid, err = getUserContextId(); err != nil {
				return err
			}
			if apiGetReqOptions.AccessToken, err = getAccessToken(); err != nil {
				return err
			}

			// The first argument is either a basepath (must start with /) or an API name
			apiGetReqOptions.ApiBasePath = args[0]
			if len(args) > 1 {
				// Is the API path valid?
				if whiskErr, ok := isValidRelpath(args[1]); !ok {
					return whiskErr
				}
				apiPath = args[1]
				apiGetReqOptions.ApiRelPath = apiPath
			}
			if len(args) > 2 {
				// Is the API verb valid?
				if whiskErr, ok := IsValidApiVerb(args[2]); !ok {
					return whiskErr
				}
				apiVerb = strings.ToUpper(args[2])
				apiGetReqOptions.ApiVerb = apiVerb
			}

			retApi, _, err = Client.Apis.Get(apiGetReq, apiGetReqOptions)
			if err != nil {
				whisk.Debug(whisk.DbgError, "Client.Apis.Get(%#v, %#v) error: %s\n", apiGetReq, apiGetReqOptions, err)
				errMsg := wski18n.T("Unable to obtain the API list: {{.err}}", map[string]interface{}{"err": err})
				whiskErr := whisk.MakeWskErrorFromWskError(errors.New(errMsg), err, whisk.EXIT_CODE_ERR_GENERAL,
					whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE)
				return whiskErr
			}
			whisk.Debug(whisk.DbgInfo, "Client.Apis.Get returned: %#v\n", retApi)
			// Cast to a common type to allow for code to print out apilist response or apiget response
			retApiArray = (*whisk.RetApiArray)(retApi)
		}
		//Checks for any order flags being passed
		sortByName := Flags.common.nameSort
		// Display the APIs - applying any specified filtering
		if Flags.common.full {
			fmt.Fprintf(color.Output,
				wski18n.T("{{.ok}} APIs\n",
					map[string]interface{}{
						"ok": color.GreenString("ok:"),
					}))
			for i := 0; i < len(retApiArray.Apis); i++ {
				orderFilteredList = append(orderFilteredList, genFilteredList(retApiArray.Apis[i].ApiValue, apiPath, apiVerb)...)
			}
			printList(orderFilteredList, sortByName) // Sends an array of structs that contains specified variables that are not truncated
		} else {
			if len(retApiArray.Apis) > 0 {
				// Dynamically create the output format string based on the maximum size of the
				// fully qualified action name and the API Name.
				maxActionNameSize := min(40, max(len("Action"), getLargestActionNameSize(retApiArray, apiPath, apiVerb)))
				maxApiNameSize := min(30, max(len("API Name"), getLargestApiNameSize(retApiArray, apiPath, apiVerb)))
				fmtString = "%-" + strconv.Itoa(maxActionNameSize) + "s %7s %" + strconv.Itoa(maxApiNameSize+1) + "s  %s\n"
				fmt.Fprintf(color.Output,
					wski18n.T("{{.ok}} APIs\n",
						map[string]interface{}{
							"ok": color.GreenString("ok:"),
						}))
				for i := 0; i < len(retApiArray.Apis); i++ {
					orderFilteredRow = append(orderFilteredRow, genFilteredRow(retApiArray.Apis[i].ApiValue, apiPath, apiVerb, maxActionNameSize, maxApiNameSize)...)
				}
				printList(orderFilteredRow, sortByName) // Sends an array of structs that contains specified variables that are truncated
			} else {
				fmt.Fprintf(color.Output,
					wski18n.T("{{.ok}} APIs\n",
						map[string]interface{}{
							"ok": color.GreenString("ok:"),
						}))
				printList(orderFilteredRow, sortByName) // Sends empty orderFilteredRow so that defaultHeader can be printed
			}
		}

		return nil
	},
}

// genFilteredList(resultApi, api) generates an array of
//      ApiFilteredLists for the purpose of ordering and printing in a list form.
//      NOTE: genFilteredRow() generates entries with one line per configuration
//         property (action name, verb, api name, api gw url)
func genFilteredList(resultApi *whisk.RetApi, apiPath string, apiVerb string) []whisk.ApiFilteredList {
	var orderInfo whisk.ApiFilteredList
	var orderInfoArr []whisk.ApiFilteredList
	baseUrl := strings.TrimSuffix(resultApi.BaseUrl, "/")
	apiName := resultApi.Swagger.Info.Title
	basePath := resultApi.Swagger.BasePath
	if resultApi.Swagger != nil && resultApi.Swagger.Paths != nil {
		for path := range resultApi.Swagger.Paths {
			whisk.Debug(whisk.DbgInfo, "genFilteredApi: comparing api relpath: '%s'\n", path)
			if len(apiPath) == 0 || path == apiPath {
				whisk.Debug(whisk.DbgInfo, "genFilteredList: relpath matches\n")
				for op, opv := range resultApi.Swagger.Paths[path].MakeOperationMap() {
					whisk.Debug(whisk.DbgInfo, "genFilteredList: comparing operation: '%s'\n", op)
					if len(apiVerb) == 0 || strings.ToLower(op) == strings.ToLower(apiVerb) {
						whisk.Debug(whisk.DbgInfo, "genFilteredList: operation matches: %#v\n", opv)
						var actionName string
						if opv.XOpenWhisk == nil {
							actionName = ""
						} else if len(opv.XOpenWhisk.Package) > 0 {
							actionName = "/" + opv.XOpenWhisk.Namespace + "/" + opv.XOpenWhisk.Package + "/" + opv.XOpenWhisk.ActionName
						} else {
							actionName = "/" + opv.XOpenWhisk.Namespace + "/" + opv.XOpenWhisk.ActionName
						}
						orderInfo = AssignListInfo(actionName, op, apiName, basePath, path, baseUrl+path)
						whisk.Debug(whisk.DbgInfo, "Appening to orderInfoArr: %s %s\n", orderInfo.RelPath)
						orderInfoArr = append(orderInfoArr, orderInfo)
					}
				}
			}
		}
	}
	return orderInfoArr
}

// genFilteredRow(resultApi, api, maxApiNameSize, maxApiNameSize) generates an array of
//      ApiFilteredRows for the purpose of ordering and printing in a list form by parsing and
//      initializing vaules for each individual ApiFilteredRow struct.
//      NOTE: Large action and api name values will be truncated by their associated max size parameters.
func genFilteredRow(resultApi *whisk.RetApi, apiPath string, apiVerb string, maxActionNameSize int, maxApiNameSize int) []whisk.ApiFilteredRow {
	var orderInfo whisk.ApiFilteredRow
	var orderInfoArr []whisk.ApiFilteredRow
	baseUrl := strings.TrimSuffix(resultApi.BaseUrl, "/")
	apiName := resultApi.Swagger.Info.Title
	basePath := resultApi.Swagger.BasePath
	if resultApi.Swagger != nil && resultApi.Swagger.Paths != nil {
		for path := range resultApi.Swagger.Paths {
			whisk.Debug(whisk.DbgInfo, "genFilteredRow: comparing api relpath: '%s'\n", path)
			if len(apiPath) == 0 || path == apiPath {
				whisk.Debug(whisk.DbgInfo, "genFilteredRow: relpath matches\n")
				for op, opv := range resultApi.Swagger.Paths[path].MakeOperationMap() {
					whisk.Debug(whisk.DbgInfo, "genFilteredRow: comparing operation: '%s'\n", op)
					if len(apiVerb) == 0 || strings.ToLower(op) == strings.ToLower(apiVerb) {
						whisk.Debug(whisk.DbgInfo, "genFilteredRow: operation matches: %#v\n", opv)
						var actionName string
						if opv.XOpenWhisk == nil {
							actionName = ""
						} else if len(opv.XOpenWhisk.Package) > 0 {
							actionName = "/" + opv.XOpenWhisk.Namespace + "/" + opv.XOpenWhisk.Package + "/" + opv.XOpenWhisk.ActionName
						} else {
							actionName = "/" + opv.XOpenWhisk.Namespace + "/" + opv.XOpenWhisk.ActionName
						}
						orderInfo = AssignRowInfo(actionName[0:min(len(actionName), maxActionNameSize)], op, apiName[0:min(len(apiName), maxApiNameSize)], basePath, path, baseUrl+path)
						orderInfo.FmtString = fmtString
						whisk.Debug(whisk.DbgInfo, "Appening to orderInfoArr: %s %s\n", orderInfo.RelPath)
						orderInfoArr = append(orderInfoArr, orderInfo)
					}
				}
			}
		}
	}
	return orderInfoArr
}

// AssignRowInfo(actionName, verb, apiName, basePath, relPath, url) assigns
//      the given vaules to and initializes an ApiFilteredRow struct, then returns it.
func AssignRowInfo(actionName string, verb string, apiName string, basePath string, relPath string, url string) whisk.ApiFilteredRow {
	var orderInfo whisk.ApiFilteredRow

	orderInfo.ActionName = actionName
	orderInfo.Verb = verb
	orderInfo.ApiName = apiName
	orderInfo.BasePath = basePath
	orderInfo.RelPath = relPath
	orderInfo.Url = url

	return orderInfo
}

// AssignListInfo(actionName, verb, apiName, basePath, relPath, url) assigns
//      the given vaules to and initializes an ApiFilteredList struct, then returns it.
func AssignListInfo(actionName string, verb string, apiName string, basePath string, relPath string, url string) whisk.ApiFilteredList {
	var orderInfo whisk.ApiFilteredList

	orderInfo.ActionName = actionName
	orderInfo.Verb = verb
	orderInfo.ApiName = apiName
	orderInfo.BasePath = basePath
	orderInfo.RelPath = relPath
	orderInfo.Url = url

	return orderInfo
}

func getLargestActionNameSize(retApiArray *whisk.RetApiArray, apiPath string, apiVerb string) int {
	var maxNameSize = 0
	for i := 0; i < len(retApiArray.Apis); i++ {
		var resultApi = retApiArray.Apis[i].ApiValue
		if resultApi.Swagger != nil && resultApi.Swagger.Paths != nil {
			for path := range resultApi.Swagger.Paths {
				whisk.Debug(whisk.DbgInfo, "getLargestActionNameSize: comparing api relpath: '%s'\n", path)
				if len(apiPath) == 0 || path == apiPath {
					whisk.Debug(whisk.DbgInfo, "getLargestActionNameSize: relpath matches\n")
					for op, opv := range resultApi.Swagger.Paths[path].MakeOperationMap() {
						whisk.Debug(whisk.DbgInfo, "getLargestActionNameSize: comparing operation: '%s'\n", op)
						if len(apiVerb) == 0 || strings.ToLower(op) == strings.ToLower(apiVerb) {
							whisk.Debug(whisk.DbgInfo, "getLargestActionNameSize: operation matches: %#v\n", opv)
							var fullActionName string
							if opv.XOpenWhisk == nil {
								fullActionName = ""
							} else if len(opv.XOpenWhisk.Package) > 0 {
								fullActionName = "/" + opv.XOpenWhisk.Namespace + "/" + opv.XOpenWhisk.Package + "/" + opv.XOpenWhisk.ActionName
							} else {
								fullActionName = "/" + opv.XOpenWhisk.Namespace + "/" + opv.XOpenWhisk.ActionName
							}
							if len(fullActionName) > maxNameSize {
								maxNameSize = len(fullActionName)
							}
						}
					}
				}
			}
		}
	}
	return maxNameSize
}

func getLargestApiNameSize(retApiArray *whisk.RetApiArray, apiPath string, apiVerb string) int {
	var maxNameSize = 0
	for i := 0; i < len(retApiArray.Apis); i++ {
		var resultApi = retApiArray.Apis[i].ApiValue
		apiName := resultApi.Swagger.Info.Title
		if resultApi.Swagger != nil && resultApi.Swagger.Paths != nil {
			for path := range resultApi.Swagger.Paths {
				whisk.Debug(whisk.DbgInfo, "getLargestActionNameSize: comparing api relpath: '%s'\n", path)
				if len(apiPath) == 0 || path == apiPath {
					whisk.Debug(whisk.DbgInfo, "getLargestActionNameSize: relpath matches\n")
					for op, opv := range resultApi.Swagger.Paths[path].MakeOperationMap() {
						whisk.Debug(whisk.DbgInfo, "getLargestActionNameSize: comparing operation: '%s'\n", op)
						if len(apiVerb) == 0 || strings.ToLower(op) == strings.ToLower(apiVerb) {
							whisk.Debug(whisk.DbgInfo, "getLargestActionNameSize: operation matches: %#v\n", opv)
							if len(apiName) > maxNameSize {
								maxNameSize = len(apiName)
							}
						}
					}
				}
			}
		}
	}
	return maxNameSize
}

func generatePathParameters(relativePath string) ([]whisk.ApiParameter, error) {
	pathParams := []whisk.ApiParameter{}

	pathParamNames, err := getPathParameterNames(relativePath)
	if len(pathParamNames) > 0 && err == nil {
		// Only create unique swagger entries
		var uniqueParamNames []string
		for _, name := range pathParamNames {
			if !contains(uniqueParamNames, name) {
				uniqueParamNames = append(uniqueParamNames, name)
			}
		}
		for _, uniqueName := range uniqueParamNames {
			whisk.Debug(whisk.DbgInfo, "Creating api parameter for '%s'\n", uniqueName)
			param := whisk.ApiParameter{Name: uniqueName, In: "path", Required: true, Type: "string",
				Description: wski18n.T("Default description for '{{.name}}'", map[string]interface{}{"name": uniqueName})}
			pathParams = append(pathParams, param)
		}
	}

	return pathParams, err
}

/*
 * if # args = 4
 * args[0] = API base path
 * args[0] = API relative path
 * args[1] = API verb
 * args[2] = Optional.  Action name (may or may not be qualified with namespace and package name)
 *
 * if # args = 3
 * args[0] = API relative path
 * args[1] = API verb
 * args[2] = Optional.  Action name (may or may not be qualified with namespace and package name)
 */
func parseApi(cmd *cobra.Command, args []string) (*whisk.Api, *QualifiedName, error) {
	var err error
	var basepath string = "/"
	var apiname string
	var basepathArgIsApiName = false

	api := new(whisk.Api)

	if len(args) > 3 {
		// Is the argument a basepath (must start with /) or an API name
		if _, ok := isValidBasepath(args[0]); !ok {
			whisk.Debug(whisk.DbgInfo, "Treating '%s' as an API name; as it does not begin with '/'\n", args[0])
			basepathArgIsApiName = true
		}
		if err, _ := isBasepathParameterized(args[0]); err != nil {
			return nil, nil, err
		}
		basepath = args[0]

		// Shift the args so the remaining code works with or without the explicit base path arg
		args = args[1:]
	}

	// Is the API path valid?
	if len(args) > 0 {
		if whiskErr, ok := isValidRelpath(args[0]); !ok {
			return nil, nil, whiskErr
		}
		api.GatewayRelPath = args[0] // Maintain case as URLs may be case-sensitive
	}

	// Attempting to use path parameters, lets validate that they provided them correctly.
	hasPathParams, err := hasPathParameters(api.GatewayRelPath)
	if err != nil {
		return nil, nil, err
	}
	// If they provided path Parameters, the response type better be http as its the only one that supports path parameters right now.
	if hasPathParams && Flags.api.resptype != "http" {
		errMsg := wski18n.T("A response type of 'http' is required when using path parameters.")
		whiskErr := whisk.MakeWskErrorFromWskError(errors.New(errMsg), err, whisk.EXIT_CODE_ERR_GENERAL,
			whisk.DISPLAY_MSG, whisk.DISPLAY_USAGE)
		return nil, nil, whiskErr
	}

	// Is the API verb valid?
	if len(args) > 1 {
		if whiskErr, ok := IsValidApiVerb(args[1]); !ok {
			return nil, nil, whiskErr
		}
		api.GatewayMethod = strings.ToUpper(args[1])
	}

	// Is the specified action name valid?
	var qName = new(QualifiedName)
	if len(args) == 3 {
		qName, err = NewQualifiedName(args[2])
		if err != nil {
			whisk.Debug(whisk.DbgError, "NewQualifiedName(%s) failed: %s\n", args[2], err)
			errMsg := wski18n.T("'{{.name}}' is not a valid action name: {{.err}}",
				map[string]interface{}{"name": args[2], "err": err})
			whiskErr := whisk.MakeWskErrorFromWskError(errors.New(errMsg), err, whisk.EXIT_CODE_ERR_GENERAL,
				whisk.DISPLAY_MSG, whisk.DISPLAY_USAGE)
			return nil, nil, whiskErr
		}
		if qName.GetEntityName() == "" {
			whisk.Debug(whisk.DbgError, "Action name '%s' is invalid\n", args[2])
			errMsg := wski18n.T("'{{.name}}' is not a valid action name.", map[string]interface{}{"name": args[2]})
			whiskErr := whisk.MakeWskErrorFromWskError(errors.New(errMsg), err, whisk.EXIT_CODE_ERR_GENERAL,
				whisk.DISPLAY_MSG, whisk.DISPLAY_USAGE)
			return nil, nil, whiskErr
		}
	}

	if len(Flags.api.apiname) > 0 {
		if basepathArgIsApiName {
			// Specifying API name as argument AND as a --apiname option value is invalid
			whisk.Debug(whisk.DbgError, "API is specified as an argument '%s' and as a flag '%s'\n", basepath, Flags.api.apiname)
			errMsg := wski18n.T("An API name can only be specified once.")
			whiskErr := whisk.MakeWskError(errors.New(errMsg), whisk.EXIT_CODE_ERR_GENERAL,
				whisk.DISPLAY_MSG, whisk.DISPLAY_USAGE)
			return nil, nil, whiskErr
		}
		apiname = Flags.api.apiname
	}

	api.Namespace = Client.Config.Namespace
	api.Action = new(whisk.ApiAction)
	var urlActionPackage string
	if len(qName.GetPackageName()) > 0 {
		urlActionPackage = qName.GetPackageName()
	} else {
		urlActionPackage = "default"
	}
	backendUrl := Client.Config.Host + "/api/v1/web/" + qName.GetNamespace() + "/" + urlActionPackage + "/" + qName.GetEntity() + ".http"
	if !strings.HasPrefix(backendUrl, "http") {
		backendUrl = "https://" + backendUrl
	}
	api.Action.BackendUrl = backendUrl
	api.Action.BackendMethod = api.GatewayMethod
	api.Action.Name = qName.GetEntityName()
	api.Action.Namespace = qName.GetNamespace()
	api.Action.Auth = Client.Config.AuthToken
	api.ApiName = apiname
	api.GatewayBasePath = basepath
	if !basepathArgIsApiName {
		api.Id = "API:" + api.Namespace + ":" + api.GatewayBasePath
	}
	api.PathParameters, err = generatePathParameters(api.GatewayRelPath)

	whisk.Debug(whisk.DbgInfo, "Parsed api struct: %#v\n", api)
	return api, qName, err
}

func parseSwaggerApi(configfile string, namespace string) (*whisk.Api, error) {
	// Test is for completeness, but this situation should only arise due to an internal error
	if len(configfile) == 0 {
		whisk.Debug(whisk.DbgError, "No swagger file is specified\n")
		errMsg := wski18n.T("A configuration file was not specified.")
		whiskErr := whisk.MakeWskError(errors.New(errMsg), whisk.EXIT_CODE_ERR_GENERAL,
			whisk.DISPLAY_MSG, whisk.DISPLAY_USAGE)
		return nil, whiskErr
	}

	swagger, err := ReadFile(configfile)
	if err != nil {
		whisk.Debug(whisk.DbgError, "readFile(%s) error: %s\n", configfile, err)
		errMsg := wski18n.T("Error reading swagger file '{{.name}}': {{.err}}",
			map[string]interface{}{"name": configfile, "err": err})
		whiskErr := whisk.MakeWskErrorFromWskError(errors.New(errMsg), err, whisk.EXIT_CODE_ERR_GENERAL,
			whisk.DISPLAY_MSG, whisk.DISPLAY_USAGE)
		return nil, whiskErr
	}

	// Check if this swagger is in JSON or YAML format
	isYaml := strings.HasSuffix(configfile, yamlFileExtension) || strings.HasSuffix(configfile, ymlFileExtension)
	if isYaml {
		whisk.Debug(whisk.DbgInfo, "Converting YAML formated API configuration into JSON\n")
		jsonbytes, err := yaml.YAMLToJSON([]byte(swagger))
		if err != nil {
			whisk.Debug(whisk.DbgError, "yaml.YAMLToJSON() error: %s\n", err)
			errMsg := wski18n.T("Unable to parse YAML configuration file: {{.err}}", map[string]interface{}{"err": err})
			whiskErr := whisk.MakeWskError(errors.New(errMsg), whisk.EXIT_CODE_ERR_GENERAL,
				whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE)
			return nil, whiskErr
		}
		swagger = string(jsonbytes)
	}

	// Parse the JSON into a swagger object
	swaggerObj := new(whisk.ApiSwagger)
	err = json.Unmarshal([]byte(swagger), swaggerObj)
	if err != nil {
		whisk.Debug(whisk.DbgError, "JSON parse of '%s' error: %s\n", configfile, err)
		errMsg := wski18n.T("Error parsing swagger file '{{.name}}': {{.err}}",
			map[string]interface{}{"name": configfile, "err": err})
		whiskErr := whisk.MakeWskErrorFromWskError(errors.New(errMsg), err, whisk.EXIT_CODE_ERR_GENERAL,
			whisk.DISPLAY_MSG, whisk.DISPLAY_USAGE)
		return nil, whiskErr
	}

	if swaggerObj.BasePath == "" || swaggerObj.SwaggerName == "" || swaggerObj.Info == nil || swaggerObj.Paths == nil {
		whisk.Debug(whisk.DbgError, "Swagger file is invalid.\n", configfile, err)
		errMsg := wski18n.T("Swagger file is invalid (missing basePath, info, paths, or swagger fields)")
		whiskErr := whisk.MakeWskError(errors.New(errMsg), whisk.EXIT_CODE_ERR_GENERAL,
			whisk.DISPLAY_MSG, whisk.DISPLAY_USAGE)
		return nil, whiskErr
	}

	if _, ok := isValidBasepath(swaggerObj.BasePath); !ok {
		whisk.Debug(whisk.DbgError, "Swagger file basePath is invalid.\n", configfile, err)
		errMsg := wski18n.T("Swagger file basePath must start with a leading slash (/)")
		whiskErr := whisk.MakeWskError(errors.New(errMsg), whisk.EXIT_CODE_ERR_GENERAL,
			whisk.DISPLAY_MSG, whisk.DISPLAY_USAGE)
		return nil, whiskErr
	}

	api := new(whisk.Api)
	api.Namespace = namespace
	api.Swagger = swagger

	return api, nil
}

func getAccessToken() (string, error) {
	var token string = "DUMMY TOKEN"
	var err error

	// If the api gw access token override has been set, use it instead of the default
	if len(ApiGwAccessToken) > 0 {
		token = ApiGwAccessToken
		whisk.Debug(whisk.DbgInfo, "API GW access token override used\n")
	} else {
		props, errprops := ReadProps(Properties.PropsFile)
		if errprops == nil {
			if len(props["APIGW_ACCESS_TOKEN"]) > 0 {
				token = props["APIGW_ACCESS_TOKEN"]
			}
		} else {
			whisk.Debug(whisk.DbgError, "readProps(%s) failed: %s\n", Properties.PropsFile, err)
			errStr := wski18n.T("Unable to obtain the API Gateway access token from the properties file: {{.err}}", map[string]interface{}{"err": err})
			err = whisk.MakeWskError(errors.New(errStr), whisk.EXIT_CODE_ERR_GENERAL, whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE)
		}
	}

	return token, err
}

func getUserContextId() (string, error) {
	var guid string
	var err error

	// If the context id override has been set, use it instead of the default
	if len(ContextId) > 0 {
		guid = ContextId
	} else {
		props, errprops := ReadProps(Properties.PropsFile)
		if errprops == nil {
			if len(props["AUTH"]) > 0 {
				guid = strings.Split(props["AUTH"], ":")[0]
			} else {
				whisk.Debug(whisk.DbgError, "AUTH property not set in properties file: '%s'\n", Properties.PropsFile)
				errStr := wski18n.T("Authorization key is not configured (--auth is required)")
				err = whisk.MakeWskError(errors.New(errStr), whisk.EXIT_CODE_ERR_GENERAL, whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE)
			}
		} else {
			whisk.Debug(whisk.DbgError, "readProps(%s) failed: %s\n", Properties.PropsFile, err)
			errStr := wski18n.T("Unable to obtain the auth key from the properties file: {{.err}}", map[string]interface{}{"err": err})
			err = whisk.MakeWskError(errors.New(errStr), whisk.EXIT_CODE_ERR_GENERAL, whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE)
		}
	}

	return guid, err
}

///////////
// Flags //
///////////

func init() {

	apiCreateCmd.Flags().StringVarP(&Flags.api.apiname, "apiname", "n", "", wski18n.T("Friendly name of the API; ignored when CFG_FILE is specified (default BASE_PATH)"))
	apiCreateCmd.Flags().StringVarP(&Flags.api.configfile, "config-file", "c", "", wski18n.T("`CFG_FILE` containing API configuration in swagger JSON format"))
	apiCreateCmd.Flags().StringVar(&Flags.api.resptype, "response-type", "json", wski18n.T("Set the web action response `TYPE`. Possible values are html, http, json, text, svg"))
	apiGetCmd.Flags().BoolVarP(&Flags.common.detail, "full", "f", false, wski18n.T("display full API configuration details"))
	apiGetCmd.Flags().StringVarP(&Flags.common.format, "format", "", formatOptionJson, wski18n.T("Specify the API output `TYPE`, either json or yaml"))
	apiListCmd.Flags().IntVarP(&Flags.common.skip, "skip", "s", 0, wski18n.T("exclude the first `SKIP` number of actions from the result"))
	apiListCmd.Flags().IntVarP(&Flags.common.limit, "limit", "l", 30, wski18n.T("only return `LIMIT` number of actions from the collection"))
	apiListCmd.Flags().BoolVarP(&Flags.common.nameSort, "name-sort", "n", false, wski18n.T("sorts a list alphabetically by order of [BASE_PATH | API_NAME], API_PATH, then API_VERB; only applicable within the limit/skip returned entity block"))
	apiListCmd.Flags().BoolVarP(&Flags.common.full, "full", "f", false, wski18n.T("display full description of each API"))
	apiCmd.AddCommand(
		apiCreateCmd,
		apiGetCmd,
		apiDeleteCmd,
		apiListCmd,
	)
}
