/*
 * 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
	CONCURRENCY_LIMIT = 1
	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"
	BAL_BIN_EXT       = ".balx"
	RUBY_EXT          = ".rb"
	GO_EXT            = ".go"
	NODE_JS           = "nodejs"
	PYTHON            = "python"
	JAVA              = "java"
	SWIFT             = "swift"
	PHP               = "php"
	RUBY              = "ruby"
	GO                = "go"
	BAL               = "ballerina"
	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),
		cmd.LocalFlags().Changed(CONCURRENCY_FLAG),
		Flags.action.memory,
		Flags.action.logsize,
		Flags.action.timeout,
		Flags.action.concurrency)

	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 || ext == BAL_BIN_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 == GO_EXT {
		exec.Kind = fmt.Sprintf("%s:%s", GO, DEFAULT)
	} else if ext == BAL_BIN_EXT {
		exec.Kind = fmt.Sprintf("%s:%s", BAL, 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
	case GO:
		extension = GO_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 && exec.Code == nil && *exec.Binary == false {
		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, concurrencySet bool, memory int, logSize int, timeout int, concurrency int) *whisk.Limits {
	var limits *whisk.Limits

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

		if memorySet {
			limits.Memory = &memory
		}

		if logSizeSet {
			limits.Logsize = &logSize
		}

		if timeoutSet {
			limits.Timeout = &timeout
		}

		if concurrencySet {
			limits.Concurrency = &concurrency
		}
	}

	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().IntVarP(&Flags.action.concurrency, CONCURRENCY_FLAG, "c", CONCURRENCY_LIMIT, wski18n.T("the maximum intra-container concurrent activation `LIMIT` 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().IntVarP(&Flags.action.concurrency, CONCURRENCY_FLAG, "c", CONCURRENCY_LIMIT, wski18n.T("the maximum intra-container concurrent activation `LIMIT` 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,
	)
}
