/*
 * 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 (
	"encoding/base64"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"math/rand"
	"os"
	"path/filepath"
	"reflect"
	"strings"
	"time"

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

	"github.com/fatih/color"
	"github.com/mattn/go-colorable"
	"github.com/spf13/cobra"
)

const (
	MEMORY_LIMIT      = 256
	TIMEOUT_LIMIT     = 60000
	LOGSIZE_LIMIT     = 10
	ACTIVATION_ID     = "activationId"
	WEB_EXPORT_ANNOT  = "web-export"
	RAW_HTTP_ANNOT    = "raw-http"
	FINAL_ANNOT       = "final"
	WEB_SECURE_ANNOT  = "require-whisk-auth"
	NODE_JS_EXT       = ".js"
	PYTHON_EXT        = ".py"
	JAVA_EXT          = ".jar"
	SWIFT_EXT         = ".swift"
	ZIP_EXT           = ".zip"
	PHP_EXT           = ".php"
	RUBY_EXT          = ".rb"
	NODE_JS           = "nodejs"
	PYTHON            = "python"
	JAVA              = "java"
	SWIFT             = "swift"
	PHP               = "php"
	RUBY              = "ruby"
	DEFAULT           = "default"
	BLACKBOX          = "blackbox"
	SEQUENCE          = "sequence"
	FETCH_CODE        = true
	DO_NOT_FETCH_CODE = false
	ACTION_UPDATE     = true
	ACTION_CREATE     = false
	MAX_JS_INT        = 1<<53 - 1
)

var actionCmd = &cobra.Command{
	Use:   "action",
	Short: wski18n.T("work with actions"),
}

var actionCreateCmd = &cobra.Command{
	Use:           "create ACTION_NAME ACTION",
	Short:         wski18n.T("create a new action"),
	SilenceUsage:  true,
	SilenceErrors: true,
	PreRunE:       SetupClientConfig,
	RunE: func(cmd *cobra.Command, args []string) error {
		var action *whisk.Action
		var err error

		if whiskErr := CheckArgs(
			args,
			1,
			2,
			"Action create",
			wski18n.T("An action name and code artifact are required.")); whiskErr != nil {
			return whiskErr
		}

		if action, err = parseAction(cmd, args, false); err != nil {
			return actionParseError(cmd, args, err)
		}

		if action, err = augmentAction(cmd, args, action, ACTION_CREATE); err != nil {
			return actionParseError(cmd, args, err)
		}

		if _, _, err = Client.Actions.Insert(action, false); err != nil {
			return actionInsertError(action, err)
		}

		printActionCreated(action.Name)

		return nil
	},
}

var actionUpdateCmd = &cobra.Command{
	Use:           "update ACTION_NAME [ACTION]",
	Short:         wski18n.T("update an existing action, or create an action if it does not exist"),
	SilenceUsage:  true,
	SilenceErrors: true,
	PreRunE:       SetupClientConfig,
	RunE: func(cmd *cobra.Command, args []string) error {
		var action *whisk.Action
		var err error

		if whiskErr := CheckArgs(
			args,
			1,
			2,
			"Action update",
			wski18n.T("An action name is required. A code artifact is optional.")); whiskErr != nil {
			return whiskErr
		}

		if action, err = parseAction(cmd, args, true); err != nil {
			return actionParseError(cmd, args, err)
		}

		if action, err = augmentAction(cmd, args, action, ACTION_UPDATE); err != nil {
			return actionParseError(cmd, args, err)
		}

		if _, _, err = Client.Actions.Insert(action, true); err != nil {
			return actionInsertError(action, err)
		}

		printActionUpdated(action.Name)

		return nil
	},
}

var actionInvokeCmd = &cobra.Command{
	Use:           "invoke ACTION_NAME",
	Short:         wski18n.T("invoke action"),
	SilenceUsage:  true,
	SilenceErrors: true,
	PreRunE:       SetupClientConfig,
	RunE: func(cmd *cobra.Command, args []string) error {
		var err error
		var qualifiedName = new(QualifiedName)
		var parameters interface{}

		if whiskErr := CheckArgs(
			args,
			1,
			1,
			"Action invoke",
			wski18n.T("An action name is required.")); whiskErr != nil {
			return whiskErr
		}

		if qualifiedName, err = NewQualifiedName(args[0]); err != nil {
			return NewQualifiedNameError(args[0], err)
		}

		parameters = getParameters(Flags.common.param, false, false)
		blocking := Flags.common.blocking || Flags.action.result
		resultOnly := Flags.action.result
		header := !resultOnly

		res, err := invokeAction(
			*qualifiedName,
			parameters,
			blocking,
			resultOnly)

		return printInvocationResponse(*qualifiedName, blocking, header, res, err)
	},
}

func invokeAction(
	qualifiedName QualifiedName,
	parameters interface{},
	blocking bool,
	result bool) (map[string]interface{}, error) {
	// TODO remove all global modifiers
	Client.Namespace = qualifiedName.GetNamespace()
	res, _, err := Client.Actions.Invoke(
		qualifiedName.GetEntityName(),
		parameters,
		blocking,
		result)
	return res, err
}

func printInvocationResponse(
	qualifiedName QualifiedName,
	blocking bool,
	header bool,
	result map[string]interface{},
	err error) error {
	if err == nil {
		printInvocationMsg(qualifiedName, blocking, header, result, color.Output)
	} else {
		if !blocking {
			return handleInvocationError(err, qualifiedName.GetEntityName())
		} else {
			return printFailedBlockingInvocationResponse(qualifiedName, header, result, err)
		}
	}

	return err
}

func printFailedBlockingInvocationResponse(
	qualifiedName QualifiedName,
	header bool,
	result map[string]interface{},
	err error) error {
	if isBlockingTimeout(err) {
		printBlockingTimeoutMsg(
			qualifiedName.GetNamespace(),
			qualifiedName.GetEntityName(),
			getValueFromJSONResponse(ACTIVATION_ID, result))
		return err
	} else if isApplicationError(err) {
		printInvocationMsg(
			qualifiedName,
			true,
			header,
			result,
			colorable.NewColorableStderr())
		return err
	} else {
		return handleInvocationError(err, qualifiedName.GetEntityName())
	}
}

var actionGetCmd = &cobra.Command{
	Use:           "get ACTION_NAME [FIELD_FILTER | --summary | --url]",
	Short:         wski18n.T("get action"),
	SilenceUsage:  true,
	SilenceErrors: true,
	PreRunE:       SetupClientConfig,
	RunE: func(cmd *cobra.Command, args []string) error {
		var err error
		var field string
		var action *whisk.Action
		var qualifiedName = new(QualifiedName)
		var fetchCode bool

		if whiskErr := CheckArgs(args, 1, 2, "Action get", wski18n.T("An action name is required.")); whiskErr != nil {
			return whiskErr
		}

		if !Flags.action.url && !Flags.common.summary && len(args) > 1 {
			field = args[1]

			if !fieldExists(&whisk.Action{}, field) {
				return invalidFieldFilterError(field)
			}
		}

		if qualifiedName, err = NewQualifiedName(args[0]); err != nil {
			return NewQualifiedNameError(args[0], err)
		}

		Client.Namespace = qualifiedName.GetNamespace()
		fetchCode = cmd.LocalFlags().Changed(SAVE_AS_FLAG) || cmd.LocalFlags().Changed(SAVE_FLAG)

		if action, _, err = Client.Actions.Get(qualifiedName.GetEntityName(), fetchCode); err != nil {
			return actionGetError(qualifiedName.GetEntityName(), fetchCode, err)
		}

		if Flags.action.url {
			actionURL, err := action.ActionURL(Properties.APIHost,
				DefaultOpenWhiskApiPath,
				Properties.APIVersion,
				qualifiedName.GetPackageName())
			if err != nil {
				errStr := wski18n.T("Invalid host address '{{.host}}': {{.err}}",
					map[string]interface{}{"host": Properties.APIHost, "err": err})
				werr := whisk.MakeWskError(errors.New(errStr), whisk.EXIT_CODE_ERR_GENERAL, whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE)
				return werr
			}
			printActionGetWithURL(qualifiedName.GetEntity(), actionURL)
		} else if Flags.common.summary {
			printSummary(action)
		} else if cmd.LocalFlags().Changed(SAVE_AS_FLAG) || cmd.LocalFlags().Changed(SAVE_FLAG) {
			return saveCode(*action, Flags.action.saveAs)
		} else {
			if len(field) > 0 {
				printActionGetWithField(qualifiedName.GetEntityName(), field, action)
			} else {
				printActionGet(qualifiedName.GetEntityName(), action)
			}
		}

		return nil
	},
}

var actionDeleteCmd = &cobra.Command{
	Use:           "delete ACTION_NAME",
	Short:         wski18n.T("delete action"),
	SilenceUsage:  true,
	SilenceErrors: true,
	PreRunE:       SetupClientConfig,
	RunE: func(cmd *cobra.Command, args []string) error {
		var qualifiedName = new(QualifiedName)
		var err error

		if whiskErr := CheckArgs(
			args,
			1,
			1,
			"Action delete",
			wski18n.T("An action name is required.")); whiskErr != nil {
			return whiskErr
		}

		if qualifiedName, err = NewQualifiedName(args[0]); err != nil {
			return NewQualifiedNameError(args[0], err)
		}

		Client.Namespace = qualifiedName.GetNamespace()

		if _, err = Client.Actions.Delete(qualifiedName.GetEntityName()); err != nil {
			return actionDeleteError(qualifiedName.GetEntityName(), err)
		}

		printActionDeleted(qualifiedName.GetEntityName())

		return nil
	},
}

var actionListCmd = &cobra.Command{
	Use:           "list [ NAMESPACE | PACKAGE_NAME ]",
	Short:         wski18n.T("list all actions in a namespace or actions contained in a package"),
	SilenceUsage:  true,
	SilenceErrors: true,
	PreRunE:       SetupClientConfig,
	RunE: func(cmd *cobra.Command, args []string) error {
		var qualifiedName = new(QualifiedName)
		var actions []whisk.Action
		var err error

		if whiskErr := CheckArgs(
			args,
			0,
			1,
			"Action list",
			wski18n.T("An optional namespace is the only valid argument.")); whiskErr != nil {
			return whiskErr
		}

		if len(args) == 1 {
			if qualifiedName, err = NewQualifiedName(args[0]); err != nil {
				return NewQualifiedNameError(args[0], err)
			}

			Client.Namespace = qualifiedName.GetNamespace()
		}

		options := &whisk.ActionListOptions{
			Skip:  Flags.common.skip,
			Limit: Flags.common.limit,
		}

		if actions, _, err = Client.Actions.List(qualifiedName.GetEntityName(), options); err != nil {
			return actionListError(qualifiedName.GetEntityName(), options, err)
		}

		sortByName := Flags.common.nameSort
		printList(actions, sortByName)

		return nil
	},
}

func parseAction(cmd *cobra.Command, args []string, update bool) (*whisk.Action, error) {
	var err error
	var existingAction *whisk.Action
	var paramArgs []string
	var annotArgs []string
	var parameters interface{}
	var annotations interface{}

	var qualifiedName = new(QualifiedName)

	if qualifiedName, err = NewQualifiedName(args[0]); err != nil {
		return nil, NewQualifiedNameError(args[0], err)
	}

	Client.Namespace = qualifiedName.GetNamespace()
	action := new(whisk.Action)
	action.Name = qualifiedName.GetEntityName()
	action.Namespace = qualifiedName.GetNamespace()
	action.Limits = getLimits(
		cmd.LocalFlags().Changed(MEMORY_FLAG),
		cmd.LocalFlags().Changed(LOG_SIZE_FLAG),
		cmd.LocalFlags().Changed(TIMEOUT_FLAG),
		Flags.action.memory,
		Flags.action.logsize,
		Flags.action.timeout)

	paramArgs = Flags.common.param
	annotArgs = Flags.common.annotation

	if len(paramArgs) > 0 {
		if parameters, err = getJSONFromStrings(paramArgs, true); err != nil {
			return nil, getJSONFromStringsParamError(paramArgs, true, err)
		}

		action.Parameters = parameters.(whisk.KeyValueArr)
	}

	if len(annotArgs) > 0 {
		if annotations, err = getJSONFromStrings(annotArgs, true); err != nil {
			return nil, getJSONFromStringsAnnotError(annotArgs, true, err)
		}

		action.Annotations = annotations.(whisk.KeyValueArr)
	}

	if len(Flags.action.kind) > 0 && len(Flags.action.docker) > 0 {
		errStr := wski18n.T("Cannot specify both --kind and --docker at the same time.")
		return nil, whisk.MakeWskError(errors.New(errStr), whisk.NOT_ALLOWED, whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE)
	}

	if Flags.action.copy {
		var copiedQualifiedName = new(QualifiedName)

		if copiedQualifiedName, err = NewQualifiedName(args[1]); err != nil {
			return nil, NewQualifiedNameError(args[1], err)
		}

		Client.Namespace = copiedQualifiedName.GetNamespace()

		if existingAction, _, err = Client.Actions.Get(copiedQualifiedName.GetEntityName(), FETCH_CODE); err != nil {
			return nil, actionGetError(copiedQualifiedName.GetEntityName(), FETCH_CODE, err)
		}

		Client.Namespace = qualifiedName.GetNamespace()
		action.Exec = existingAction.Exec
		action.Parameters = append(action.Parameters, existingAction.Parameters...)
		action.Annotations = append(action.Annotations, existingAction.Annotations...)
	} else if Flags.action.sequence {
		if len(args) == 2 {
			action.Exec = new(whisk.Exec)
			action.Exec.Kind = SEQUENCE
			action.Exec.Components = csvToQualifiedActions(args[1])
		} else {
			return nil, noArtifactError()
		}
	} else if len(args) > 1 || len(Flags.action.docker) > 0 {
		action.Exec, err = getExec(args, Flags.action)
		if err != nil {
			return nil, err
		}
	} else if !update {
		return nil, noArtifactError()
	}

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

func augmentAction(cmd *cobra.Command, args []string, action *whisk.Action, update bool) (*whisk.Action, error) {
	var err error
	var existingAction *whisk.Action = nil
	var augmentedAction *whisk.Action = new(whisk.Action)
	*augmentedAction = *action

	if update {
		if existingAction, _, err = Client.Actions.Get(action.Name, DO_NOT_FETCH_CODE); err != nil {
			whiskErr, isWhiskError := err.(*whisk.WskError)

			if (isWhiskError && whiskErr.ExitCode != whisk.EXIT_CODE_NOT_FOUND) || !isWhiskError {
				return nil, actionGetError(action.Name, DO_NOT_FETCH_CODE, err)
			}
		}
	}

	// Augment the action's annotations with the --web related annotations
	if augmentedAction, err = augmentWebArg(cmd, args, action, augmentedAction, existingAction); err != nil {
		return nil, err
	}

	// Augment the action's annotations with the --web-secure related annotations
	if augmentedAction, err = augmentWebSecureArg(cmd, args, action, augmentedAction, existingAction); err != nil {
		return nil, err
	}

	whisk.Debug(whisk.DbgInfo, "Augmented action struct: %#v\n", augmentedAction)
	return augmentedAction, err
}

func augmentWebArg(cmd *cobra.Command, args []string, action *whisk.Action, augmentedAction *whisk.Action, existingAction *whisk.Action) (*whisk.Action, error) {
	var err error
	preserveAnnotations := action.Annotations == nil

	if cmd.LocalFlags().Changed(WEB_FLAG) {
		augmentedAction.Annotations, err = webAction(Flags.action.web, action.Annotations, action.Name, preserveAnnotations, existingAction)
		if existingAction != nil && err == nil {
			// Always carry forward any existing --web-secure annotation value
			// Although it can be overwritten later if --web-secure is set
			webSecureAnnotations := getWebSecureAnnotations(existingAction)
			if len(webSecureAnnotations) > 0 {
				augmentedAction.Annotations = augmentedAction.Annotations.AppendKeyValueArr(webSecureAnnotations)
			}
		}
	}

	if err != nil {
		return nil, err
	}

	whisk.Debug(whisk.DbgInfo, "augmentWebArg: Augmented action struct: %#v\n", augmentedAction)
	return augmentedAction, nil
}

/*
 * Return a whisk.Action augmented with --web-secure annotation updates
 * originalAction:  a action constructed from command line argument
 * action:          an action constructed from command line args + possible other augmentation (i.e. --web annotations)
 * existingAction:  on an action update, this is the existing action
 */
func augmentWebSecureArg(cmd *cobra.Command, args []string, originalAction *whisk.Action, action *whisk.Action, existingAction *whisk.Action) (*whisk.Action, error) {
	preserveAnnotations := action.Annotations == nil
	var augmentedAction *whisk.Action = new(whisk.Action)
	*augmentedAction = *action
	disableWebAction := strings.ToLower(Flags.action.web) == "false" || strings.ToLower(Flags.action.web) == "no"
	isWebSecureFlagValidToUse := action.WebAction() || (existingAction != nil && existingAction.WebAction() && !disableWebAction)

	// Process the --web-secure flag when set
	if cmd.LocalFlags().Changed(WEB_SECURE_FLAG) {
		// The --web-secure option is only valid when:
		//   1. action --web is set to either true or raw (i.e. web-export annotation is true)
		//   -OR-
		//   2. existing action web-export annotation is true && action --web is not false/no
		whisk.Debug(whisk.DbgInfo, "disableWebAction: %v  isWebSecureFlagValidToUse: %v\n", disableWebAction, isWebSecureFlagValidToUse)
		if !isWebSecureFlagValidToUse {
			return nil, webSecureUsageError()
		}

		// Carry forward some or all of the existing action's annotations
		//   all  -> if original command line had at least one annotation specified
		//   some -> if original command line had NO annotations, carry forward web/websecure annotation values
		if existingAction != nil {
			if preserveAnnotations {
				augmentedAction.Annotations = action.Annotations.AppendKeyValueArr(existingAction.Annotations)
			} else {
				augmentedAction.Annotations = action.Annotations.AppendKeyValueArr(getWebActionAnnotations(existingAction))
				augmentedAction.Annotations = augmentedAction.Annotations.AppendKeyValueArr(getWebSecureAnnotations(existingAction))
			}
		}
		augmentedAction.Annotations = updateWebSecureAnnotation(Flags.action.websecure, augmentedAction.Annotations)
	}

	whisk.Debug(whisk.DbgInfo, "augmentWebSecureArg: Augmented action struct: %#v\n", augmentedAction)
	return augmentedAction, nil
}

func getExec(args []string, params ActionFlags) (*whisk.Exec, error) {
	var err error
	var code string
	var exec *whisk.Exec

	exec = new(whisk.Exec)
	kind := params.kind
	isNative := params.native
	docker := params.docker
	mainEntry := params.main
	ext := ""

	if len(args) == 2 {
		artifact := args[1]
		ext = filepath.Ext(artifact)
		code, err = ReadFile(artifact)

		if err != nil {
			whisk.Debug(whisk.DbgError, "ReadFile(%s) error: %s\n", artifact, err)
			return nil, err
		}

		if ext == ZIP_EXT || ext == JAVA_EXT {
			code = base64.StdEncoding.EncodeToString([]byte(code))
		}

		exec.Code = &code
	} else if len(args) == 1 && len(docker) == 0 {
		return nil, noArtifactError()
	} else if len(args) > 1 {
		return nil, noArtifactError()
	}

	if len(kind) > 0 {
		exec.Kind = kind
	} else if len(docker) > 0 || isNative {
		exec.Kind = BLACKBOX
		if isNative {
			exec.Image = "openwhisk/dockerskeleton"
		} else {
			exec.Image = docker
		}
	} else if ext == SWIFT_EXT {
		exec.Kind = fmt.Sprintf("%s:%s", SWIFT, DEFAULT)
	} else if ext == NODE_JS_EXT {
		exec.Kind = fmt.Sprintf("%s:%s", NODE_JS, DEFAULT)
	} else if ext == PYTHON_EXT {
		exec.Kind = fmt.Sprintf("%s:%s", PYTHON, DEFAULT)
	} else if ext == JAVA_EXT {
		exec.Kind = fmt.Sprintf("%s:%s", JAVA, DEFAULT)
	} else if ext == PHP_EXT {
		exec.Kind = fmt.Sprintf("%s:%s", PHP, DEFAULT)
	} else if ext == RUBY_EXT {
		exec.Kind = fmt.Sprintf("%s:%s", RUBY, DEFAULT)
	} else {
		if ext == ZIP_EXT {
			return nil, zipKindError()
		} else {
			return nil, extensionError(ext)
		}
	}

	// Error if entry point is not specified for Java
	if len(mainEntry) != 0 {
		exec.Main = mainEntry
	} else {
		if exec.Kind == "java" {
			return nil, javaEntryError()
		}
	}

	return exec, nil
}

func getBinaryKindExtension(runtime string) (extension string) {
	switch strings.ToLower(runtime) {
	case JAVA:
		extension = JAVA_EXT
	default:
		extension = ZIP_EXT
	}

	return extension
}

func getKindExtension(runtime string) (extension string) {
	switch strings.ToLower(runtime) {
	case NODE_JS:
		extension = NODE_JS_EXT
	case PYTHON:
		extension = PYTHON_EXT
	case SWIFT:
		fallthrough
	case PHP:
		extension = fmt.Sprintf(".%s", runtime)
	case RUBY:
		extension = RUBY_EXT
	}

	return extension
}

func saveCode(action whisk.Action, filename string) (err error) {
	var code string
	var runtime string
	var exec whisk.Exec

	exec = *action.Exec
	runtime = strings.Split(exec.Kind, ":")[0]

	if strings.ToLower(runtime) == BLACKBOX {
		return cannotSaveImageError()
	} else if strings.ToLower(runtime) == SEQUENCE {
		return cannotSaveSequenceError()
	}

	if exec.Code != nil {
		code = *exec.Code
	}

	if *exec.Binary {
		decoded, _ := base64.StdEncoding.DecodeString(code)
		code = string(decoded)

		if len(filename) == 0 {
			filename = action.Name + getBinaryKindExtension(runtime)
		}
	} else {
		if len(filename) == 0 {
			filename = action.Name + getKindExtension(runtime)
		}
	}

	if exists, err := FileExists(filename); err != nil {
		return err
	} else if exists {
		return fileExistsError(filename)
	}

	if err := writeFile(filename, code); err != nil {
		return err
	}

	pwd, err := os.Getwd()
	if err != nil {
		whisk.Debug(whisk.DbgError, "os.Getwd() error: %s\n", err)
		return err
	}

	savedPath := fmt.Sprintf("%s%s%s", pwd, string(os.PathSeparator), filename)

	printSavedActionCodeSuccess(savedPath)

	return nil
}

func webAction(webMode string, annotations whisk.KeyValueArr, entityName string, preserveAnnotations bool, existingAction *whisk.Action) (whisk.KeyValueArr, error) {
	switch strings.ToLower(webMode) {
	case "yes":
		fallthrough
	case "true":
		return webActionAnnotations(preserveAnnotations, annotations, entityName, addWebAnnotations, existingAction)
	case "no":
		fallthrough
	case "false":
		return webActionAnnotations(preserveAnnotations, annotations, entityName, deleteWebAnnotations, existingAction)
	case "raw":
		return webActionAnnotations(preserveAnnotations, annotations, entityName, addRawAnnotations, existingAction)
	default:
		return nil, webInputError(webMode)
	}
}

type WebActionAnnotationMethod func(annotations whisk.KeyValueArr) whisk.KeyValueArr

func webActionAnnotations(
	preserveAnnotations bool,
	annotations whisk.KeyValueArr,
	entityName string,
	webActionAnnotationMethod WebActionAnnotationMethod,
	existingAction *whisk.Action) (whisk.KeyValueArr, error) {

	if preserveAnnotations && existingAction != nil {
		annotations = whisk.KeyValueArr.AppendKeyValueArr(annotations, existingAction.Annotations)
	}

	annotations = webActionAnnotationMethod(annotations)

	return annotations, nil
}

func addWebAnnotations(annotations whisk.KeyValueArr) whisk.KeyValueArr {
	annotations = deleteWebAnnotationKeys(annotations)
	annotations = addKeyValue(WEB_EXPORT_ANNOT, true, annotations)
	annotations = addKeyValue(RAW_HTTP_ANNOT, false, annotations)
	annotations = addKeyValue(FINAL_ANNOT, true, annotations)

	return annotations
}

func deleteWebAnnotations(annotations whisk.KeyValueArr) whisk.KeyValueArr {
	annotations = deleteWebAnnotationKeys(annotations)
	annotations = addKeyValue(WEB_EXPORT_ANNOT, false, annotations)
	annotations = addKeyValue(RAW_HTTP_ANNOT, false, annotations)
	annotations = addKeyValue(FINAL_ANNOT, false, annotations)

	return annotations
}

func addRawAnnotations(annotations whisk.KeyValueArr) whisk.KeyValueArr {
	annotations = deleteWebAnnotationKeys(annotations)
	annotations = addKeyValue(WEB_EXPORT_ANNOT, true, annotations)
	annotations = addKeyValue(RAW_HTTP_ANNOT, true, annotations)
	annotations = addKeyValue(FINAL_ANNOT, true, annotations)

	return annotations
}

func deleteWebAnnotationKeys(annotations whisk.KeyValueArr) whisk.KeyValueArr {
	annotations = deleteKey(WEB_EXPORT_ANNOT, annotations)
	annotations = deleteKey(RAW_HTTP_ANNOT, annotations)
	annotations = deleteKey(FINAL_ANNOT, annotations)

	return annotations
}

func getWebActionAnnotations(action *whisk.Action) whisk.KeyValueArr {
	var webKvArr = make(whisk.KeyValueArr, 3, 3)
	var j = 0

	var i = action.Annotations.FindKeyValue(WEB_EXPORT_ANNOT)
	if i > -1 {
		webKvArr[j] = action.Annotations[i]
		j++
	}
	i = action.Annotations.FindKeyValue(RAW_HTTP_ANNOT)
	if i > -1 {
		webKvArr[j] = action.Annotations[i]
		j++
	}
	i = action.Annotations.FindKeyValue(FINAL_ANNOT)
	if i > -1 {
		webKvArr[j] = action.Annotations[i]
		j++
	}
	return webKvArr[0:j]
}

func getWebSecureAnnotations(action *whisk.Action) whisk.KeyValueArr {
	var webKvArr = make(whisk.KeyValueArr, 1, 1)
	var j = 0

	var i = action.Annotations.FindKeyValue(WEB_SECURE_ANNOT)
	if i > -1 {
		webKvArr[j] = action.Annotations[i]
		j++
	}

	return webKvArr[0:j]
}

/*
 * Update the existing annotations with the web security annotation
 * If the current web security setting and existing setting are the "same", keep the existing value
 *   -> checking for the same "--web-secure true" setting means just checking if the two values are integers
 * If the current web security setting is "false", remove any existing setting
 */
func updateWebSecureAnnotation(websecure string, annotations whisk.KeyValueArr) whisk.KeyValueArr {
	secureSecret := webSecureSecret(websecure) // will be false when "--web-secure false"
	existingSecret := annotations.GetValue(WEB_SECURE_ANNOT)
	_, disableSecurity := secureSecret.(bool)
	_, newSecretIsInt := secureSecret.(int64)
	var existingSecretIsInt bool = false
	if existingSecret != nil {
		_, existingSecretIsInt = existingSecret.(json.Number)
	}

	if existingSecretIsInt && newSecretIsInt {
		whisk.Debug(whisk.DbgInfo, "Retaining existing secret number\n")
	} else if existingSecret != nil && disableSecurity {
		whisk.Debug(whisk.DbgInfo, "disabling web-secure; deleting annotation: %v\n", WEB_SECURE_ANNOT)
		annotations = deleteKey(WEB_SECURE_ANNOT, annotations)
	} else {
		whisk.Debug(whisk.DbgInfo, "Setting %v annotation; prior secret %v new secret %v\n",
			WEB_SECURE_ANNOT, reflect.TypeOf(existingSecret), reflect.TypeOf(secureSecret))
		annotations = annotations.AddOrReplace(&whisk.KeyValue{Key: WEB_SECURE_ANNOT, Value: secureSecret})
	}

	return annotations
}

//
// Generate a secret according to the --web-secure setting
//  true:   return a random int64
//  false:  return false, meaning no secret was returned
//  string: return the same string
func webSecureSecret(webSecureMode string) interface{} {
	switch strings.ToLower(webSecureMode) {
	case "true":
		return genWebActionSecureKey()
	case "false":
		return false
	default:
		return webSecureMode
	}
}

func getLimits(memorySet bool, logSizeSet bool, timeoutSet bool, memory int, logSize int, timeout int) *whisk.Limits {
	var limits *whisk.Limits

	if memorySet || logSizeSet || timeoutSet {
		limits = new(whisk.Limits)

		if memorySet {
			limits.Memory = &memory
		}

		if logSizeSet {
			limits.Logsize = &logSize
		}

		if timeoutSet {
			limits.Timeout = &timeout
		}
	}

	return limits
}

func nestedError(errorMessage string, err error) error {
	return whisk.MakeWskErrorFromWskError(
		errors.New(errorMessage),
		err,
		whisk.EXIT_CODE_ERR_GENERAL,
		whisk.DISPLAY_MSG,
		whisk.DISPLAY_USAGE)
}

func nonNestedError(errorMessage string) error {
	return whisk.MakeWskError(
		errors.New(errorMessage),
		whisk.EXIT_CODE_ERR_USAGE,
		whisk.DISPLAY_MSG,
		whisk.DISPLAY_USAGE)
}

func actionParseError(cmd *cobra.Command, args []string, err error) error {
	whisk.Debug(whisk.DbgError, "parseAction(%s, %s) error: %s\n", cmd, args, err)

	errMsg := wski18n.T(
		"Invalid argument(s). {{.required}}",
		map[string]interface{}{
			"required": err,
		})

	return nestedError(errMsg, err)
}

func actionInsertError(action *whisk.Action, err error) error {
	whisk.Debug(whisk.DbgError, "Client.Actions.Insert(%#v, false) error: %s\n", action, err)

	errMsg := wski18n.T(
		"Unable to create action '{{.name}}': {{.err}}",
		map[string]interface{}{
			"name": action.Name,
			"err":  err,
		})

	return nestedError(errMsg, err)
}

func getJSONFromStringsParamError(params []string, keyValueFormat bool, err error) error {
	whisk.Debug(whisk.DbgError, "getJSONFromStrings(%#v, %t) failed: %s\n", params, keyValueFormat, err)

	errMsg := wski18n.T(
		"Invalid parameter argument '{{.param}}': {{.err}}",
		map[string]interface{}{
			"param": fmt.Sprintf("%#v", params),
			"err":   err,
		})

	return nestedError(errMsg, err)
}

func getJSONFromStringsAnnotError(annots []string, keyValueFormat bool, err error) error {
	whisk.Debug(whisk.DbgError, "getJSONFromStrings(%#v, %t) failed: %s\n", annots, keyValueFormat, err)

	errMsg := wski18n.T(
		"Invalid annotation argument '{{.annotation}}': {{.err}}",
		map[string]interface{}{
			"annotation": fmt.Sprintf("%#v", annots),
			"err":        err,
		})

	return nestedError(errMsg, err)
}

func invalidFieldFilterError(field string) error {
	errMsg := wski18n.T(
		"Invalid field filter '{{.arg}}'.",
		map[string]interface{}{
			"arg": field,
		})

	return nonNestedError(errMsg)
}

func actionDeleteError(entityName string, err error) error {
	whisk.Debug(whisk.DbgError, "Client.Actions.Delete(%s) error: %s\n", entityName, err)

	errMsg := wski18n.T(
		"Unable to delete action '{{.name}}': {{.err}}",
		map[string]interface{}{
			"name": entityName,
			"err":  err,
		})

	return nestedError(errMsg, err)
}

func actionGetError(entityName string, fetchCode bool, err error) error {
	whisk.Debug(whisk.DbgError, "Client.Actions.Get(%s, %t) error: %s\n", entityName, fetchCode, err)

	errMsg := wski18n.T(
		"Unable to get action '{{.name}}': {{.err}}",
		map[string]interface{}{
			"name": entityName,
			"err":  err,
		})

	return nestedError(errMsg, err)
}

func handleInvocationError(err error, entityName string) error {
	whisk.Debug(
		whisk.DbgError,
		"Client.Actions.Invoke(%s, %t) error: %s\n",
		entityName,
		err)

	errMsg := wski18n.T(
		"Unable to invoke action '{{.name}}': {{.err}}",
		map[string]interface{}{
			"name": entityName,
			"err":  err,
		})

	return nestedError(errMsg, err)
}

func actionListError(entityName string, options *whisk.ActionListOptions, err error) error {
	whisk.Debug(whisk.DbgError, "Client.Actions.List(%s, %#v) error: %s\n", entityName, options, err)

	errMsg := wski18n.T(
		"Unable to obtain the list of actions for namespace '{{.name}}': {{.err}}",
		map[string]interface{}{
			"name": getClientNamespace(),
			"err":  err,
		})

	return nestedError(errMsg, err)
}

func webInputError(arg string) error {
	errMsg := wski18n.T(
		"Invalid argument '{{.arg}}' for --web flag. Valid input consist of 'yes', 'true', 'raw', 'false', or 'no'.",
		map[string]interface{}{
			"arg": arg,
		})

	return nonNestedError(errMsg)
}

func webSecureUsageError() error {
	errMsg := wski18n.T("The --web-secure option is only valid when the --web option is enabled.")
	return nonNestedError(errMsg)
}

func zipKindError() error {
	errMsg := wski18n.T("creating an action from a .zip artifact requires specifying the action kind explicitly")

	return nonNestedError(errMsg)
}

func noArtifactError() error {
	errMsg := wski18n.T("An action name and code artifact are required.")

	return nonNestedError(errMsg)
}

func extensionError(extension string) error {
	errMsg := wski18n.T(
		"'{{.name}}' is not a supported action runtime",
		map[string]interface{}{
			"name": extension,
		})

	return nonNestedError(errMsg)
}

func javaEntryError() error {
	errMsg := wski18n.T("Java actions require --main to specify the fully-qualified name of the main class")

	return nonNestedError(errMsg)
}

func cannotSaveImageError() error {
	return nonNestedError(wski18n.T("Cannot save Docker images"))
}

func cannotSaveSequenceError() error {
	return nonNestedError(wski18n.T("Cannot save action sequences"))
}

func fileExistsError(file string) error {
	errMsg := wski18n.T("The file '{{.file}}' already exists", map[string]interface{}{
		"file": file,
	})

	return nonNestedError(errMsg)
}

func printActionCreated(entityName string) {
	fmt.Fprintf(
		color.Output,
		wski18n.T(
			"{{.ok}} created action {{.name}}\n",
			map[string]interface{}{
				"ok":   color.GreenString("ok:"),
				"name": boldString(entityName),
			}))
}

func printActionUpdated(entityName string) {
	fmt.Fprintf(
		color.Output,
		wski18n.T(
			"{{.ok}} updated action {{.name}}\n",
			map[string]interface{}{
				"ok":   color.GreenString("ok:"),
				"name": boldString(entityName),
			}))
}

func printBlockingTimeoutMsg(namespace string, entityName string, activationID interface{}) {
	fmt.Fprintf(
		colorable.NewColorableStderr(),
		wski18n.T(
			"{{.ok}} invoked /{{.namespace}}/{{.name}}, but the request has not yet finished, with id {{.id}}\n",
			map[string]interface{}{
				"ok":        color.GreenString("ok:"),
				"namespace": boldString(namespace),
				"name":      boldString(entityName),
				"id":        boldString(activationID),
			}))
}

func printInvocationMsg(
	qualifiedName QualifiedName,
	blocking bool,
	header bool,
	response map[string]interface{},
	outputStream io.Writer) {
	if header {
		fmt.Fprintf(
			outputStream,
			wski18n.T(
				"{{.ok}} invoked /{{.namespace}}/{{.name}} with id {{.id}}\n",
				map[string]interface{}{
					"ok":        color.GreenString("ok:"),
					"namespace": boldString(qualifiedName.GetNamespace()),
					"name":      boldString(qualifiedName.GetEntityName()),
					"id":        boldString(getValueFromJSONResponse(ACTIVATION_ID, response)),
				}))
	}

	if blocking {
		printJSON(response, outputStream)
	}
}

func printActionGetWithField(entityName string, field string, action *whisk.Action) {
	fmt.Fprintf(
		color.Output,
		wski18n.T(
			"{{.ok}} got action {{.name}}, displaying field {{.field}}\n",
			map[string]interface{}{
				"ok":    color.GreenString("ok:"),
				"name":  boldString(entityName),
				"field": boldString(field),
			}))

	printField(action, field)
}

func printActionGetWithURL(entityName string, actionURL string) {
	fmt.Fprintf(
		color.Output,
		wski18n.T("{{.ok}} got action {{.name}}\n",
			map[string]interface{}{
				"ok":   color.GreenString("ok:"),
				"name": boldString(entityName),
			}))
	fmt.Println(actionURL)
}

func printActionGet(entityName string, action *whisk.Action) {
	fmt.Fprintf(
		color.Output,
		wski18n.T("{{.ok}} got action {{.name}}\n",
			map[string]interface{}{
				"ok":   color.GreenString("ok:"),
				"name": boldString(entityName),
			}))

	printJSON(action)
}

func printActionDeleted(entityName string) {
	fmt.Fprintf(
		color.Output,
		wski18n.T(
			"{{.ok}} deleted action {{.name}}\n",
			map[string]interface{}{
				"ok":   color.GreenString("ok:"),
				"name": boldString(entityName),
			}))
}

func printSavedActionCodeSuccess(name string) {
	fmt.Fprintf(
		color.Output,
		wski18n.T(
			"{{.ok}} saved action code to {{.name}}\n",
			map[string]interface{}{
				"ok":   color.GreenString("ok:"),
				"name": boldString(name),
			}))
}

// Generate a random number to be used as a web action's require-whisk-auth secret
func genWebActionSecureKey() int64 {
	r := rand.New(rand.NewSource(time.Now().Unix()))

	// Truncate integer for API GW interoperability
	return r.Int63() & MAX_JS_INT
}

// Check if the specified action is a web-action
func isWebAction(client *whisk.Client, qname QualifiedName) (*whisk.Action, error) {
	var err error = nil

	savedNs := client.Namespace
	client.Namespace = qname.GetNamespace()
	fullActionName := "/" + qname.GetNamespace() + "/" + qname.GetEntityName()

	action, _, err := client.Actions.Get(qname.GetEntityName(), DO_NOT_FETCH_CODE)

	if err != nil {
		whisk.Debug(whisk.DbgError, "client.Actions.Get(%s, %t) error: %s\n", fullActionName, DO_NOT_FETCH_CODE, err)
		whisk.Debug(whisk.DbgError, "Unable to obtain action '%s' for web action validation\n", fullActionName)
		errMsg := wski18n.T("Unable to get action '{{.name}}': {{.err}}",
			map[string]interface{}{"name": fullActionName, "err": err})
		err = whisk.MakeWskErrorFromWskError(errors.New(errMsg), err, whisk.EXIT_CODE_ERR_NETWORK, whisk.DISPLAY_MSG,
			whisk.NO_DISPLAY_USAGE)
	} else {
		err = errors.New(wski18n.T("Action '{{.name}}' is not a web action. Issue 'wsk action update \"{{.name}}\" --web true' to convert the action to a web action.",
			map[string]interface{}{"name": fullActionName}))

		if action.WebAction() {
			err = nil
		}
	}

	client.Namespace = savedNs

	return action, err
}

func init() {
	actionCreateCmd.Flags().BoolVar(&Flags.action.native, "native", false, wski18n.T("treat ACTION as native action (zip file provides a compatible executable to run)"))
	actionCreateCmd.Flags().StringVar(&Flags.action.docker, "docker", "", wski18n.T("use provided docker image (a path on DockerHub) to run the action"))
	actionCreateCmd.Flags().BoolVar(&Flags.action.copy, "copy", false, wski18n.T("treat ACTION as the name of an existing action"))
	actionCreateCmd.Flags().BoolVar(&Flags.action.sequence, "sequence", false, wski18n.T("treat ACTION as comma separated sequence of actions to invoke"))
	actionCreateCmd.Flags().StringVar(&Flags.action.kind, "kind", "", wski18n.T("the `KIND` of the action runtime (example: swift:default, nodejs:default)"))
	actionCreateCmd.Flags().StringVar(&Flags.action.main, "main", "", wski18n.T("the name of the action entry point (function or fully-qualified method name when applicable)"))
	actionCreateCmd.Flags().IntVarP(&Flags.action.timeout, TIMEOUT_FLAG, "t", TIMEOUT_LIMIT, wski18n.T("the timeout `LIMIT` in milliseconds after which the action is terminated"))
	actionCreateCmd.Flags().IntVarP(&Flags.action.memory, MEMORY_FLAG, "m", MEMORY_LIMIT, wski18n.T("the maximum memory `LIMIT` in MB for the action"))
	actionCreateCmd.Flags().IntVarP(&Flags.action.logsize, LOG_SIZE_FLAG, "l", LOGSIZE_LIMIT, wski18n.T("the maximum log size `LIMIT` in MB for the action"))
	actionCreateCmd.Flags().StringSliceVarP(&Flags.common.annotation, "annotation", "a", nil, wski18n.T("annotation values in `KEY VALUE` format"))
	actionCreateCmd.Flags().StringVarP(&Flags.common.annotFile, "annotation-file", "A", "", wski18n.T("`FILE` containing annotation values in JSON format"))
	actionCreateCmd.Flags().StringSliceVarP(&Flags.common.param, "param", "p", nil, wski18n.T("parameter values in `KEY VALUE` format"))
	actionCreateCmd.Flags().StringVarP(&Flags.common.paramFile, "param-file", "P", "", wski18n.T("`FILE` containing parameter values in JSON format"))
	actionCreateCmd.Flags().StringVar(&Flags.action.web, WEB_FLAG, "", wski18n.T("treat ACTION as a web action, a raw HTTP web action, or as a standard action; yes | true = web action, raw = raw HTTP web action, no | false = standard action"))
	actionCreateCmd.Flags().StringVar(&Flags.action.websecure, WEB_SECURE_FLAG, "", wski18n.T("secure the web action. where `SECRET` is true, false, or any string. Only valid when the ACTION is a web action"))

	actionUpdateCmd.Flags().BoolVar(&Flags.action.native, "native", false, wski18n.T("treat ACTION as native action (zip file provides a compatible executable to run)"))
	actionUpdateCmd.Flags().StringVar(&Flags.action.docker, "docker", "", wski18n.T("use provided docker image (a path on DockerHub) to run the action"))
	actionUpdateCmd.Flags().BoolVar(&Flags.action.copy, "copy", false, wski18n.T("treat ACTION as the name of an existing action"))
	actionUpdateCmd.Flags().BoolVar(&Flags.action.sequence, "sequence", false, wski18n.T("treat ACTION as comma separated sequence of actions to invoke"))
	actionUpdateCmd.Flags().StringVar(&Flags.action.kind, "kind", "", wski18n.T("the `KIND` of the action runtime (example: swift:default, nodejs:default)"))
	actionUpdateCmd.Flags().StringVar(&Flags.action.main, "main", "", wski18n.T("the name of the action entry point (function or fully-qualified method name when applicable)"))
	actionUpdateCmd.Flags().IntVarP(&Flags.action.timeout, TIMEOUT_FLAG, "t", TIMEOUT_LIMIT, wski18n.T("the timeout `LIMIT` in milliseconds after which the action is terminated"))
	actionUpdateCmd.Flags().IntVarP(&Flags.action.memory, MEMORY_FLAG, "m", MEMORY_LIMIT, wski18n.T("the maximum memory `LIMIT` in MB for the action"))
	actionUpdateCmd.Flags().IntVarP(&Flags.action.logsize, LOG_SIZE_FLAG, "l", LOGSIZE_LIMIT, wski18n.T("the maximum log size `LIMIT` in MB for the action"))
	actionUpdateCmd.Flags().StringSliceVarP(&Flags.common.annotation, "annotation", "a", []string{}, wski18n.T("annotation values in `KEY VALUE` format"))
	actionUpdateCmd.Flags().StringVarP(&Flags.common.annotFile, "annotation-file", "A", "", wski18n.T("`FILE` containing annotation values in JSON format"))
	actionUpdateCmd.Flags().StringSliceVarP(&Flags.common.param, "param", "p", []string{}, wski18n.T("parameter values in `KEY VALUE` format"))
	actionUpdateCmd.Flags().StringVarP(&Flags.common.paramFile, "param-file", "P", "", wski18n.T("`FILE` containing parameter values in JSON format"))
	actionUpdateCmd.Flags().StringVar(&Flags.action.web, WEB_FLAG, "", wski18n.T("treat ACTION as a web action, a raw HTTP web action, or as a standard action; yes | true = web action, raw = raw HTTP web action, no | false = standard action"))
	actionUpdateCmd.Flags().StringVar(&Flags.action.websecure, WEB_SECURE_FLAG, "", wski18n.T("secure the web action. where `SECRET` is true, false, or any string. Only valid when the ACTION is a web action"))

	actionInvokeCmd.Flags().StringSliceVarP(&Flags.common.param, "param", "p", []string{}, wski18n.T("parameter values in `KEY VALUE` format"))
	actionInvokeCmd.Flags().StringVarP(&Flags.common.paramFile, "param-file", "P", "", wski18n.T("`FILE` containing parameter values in JSON format"))
	actionInvokeCmd.Flags().BoolVarP(&Flags.common.blocking, "blocking", "b", false, wski18n.T("blocking invoke"))
	actionInvokeCmd.Flags().BoolVarP(&Flags.action.result, "result", "r", false, wski18n.T("blocking invoke; show only activation result (unless there is a failure)"))

	actionGetCmd.Flags().BoolVarP(&Flags.common.summary, "summary", "s", false, wski18n.T("summarize action details; parameters with prefix \"*\" are bound, \"**\" are bound and finalized"))
	actionGetCmd.Flags().BoolVarP(&Flags.action.url, "url", "r", false, wski18n.T("get action url"))
	actionGetCmd.Flags().StringVar(&Flags.action.saveAs, SAVE_AS_FLAG, "", wski18n.T("file to save action code to"))
	actionGetCmd.Flags().BoolVarP(&Flags.action.save, SAVE_FLAG, "", false, wski18n.T("save action code to file corresponding with action name"))

	actionListCmd.Flags().IntVarP(&Flags.common.skip, "skip", "s", 0, wski18n.T("exclude the first `SKIP` number of actions from the result"))
	actionListCmd.Flags().IntVarP(&Flags.common.limit, "limit", "l", 30, wski18n.T("only return `LIMIT` number of actions from the collection"))
	actionListCmd.Flags().BoolVarP(&Flags.common.nameSort, "name-sort", "n", false, wski18n.T("sorts a list alphabetically by entity name; only applicable within the limit/skip returned entity block"))

	actionCmd.AddCommand(
		actionCreateCmd,
		actionUpdateCmd,
		actionInvokeCmd,
		actionGetCmd,
		actionDeleteCmd,
		actionListCmd,
	)
}
