/*
 * Copyright 2015-2016 IBM Corporation
 *
 * Licensed 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"
    "errors"
    "fmt"
    "path/filepath"
    "io"
    "strings"

    "../../go-whisk/whisk"
    "../wski18n"

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

const MEMORY_LIMIT = 256
const TIMEOUT_LIMIT = 60000
const LOGSIZE_LIMIT = 10
const ACTIVATION_ID = "activationId"
const WEB_EXPORT_ANNOT = "web-export"
const RAW_HTTP_ANNOT = "raw-http"
const FINAL_ANNOT = "final"

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,
            2,
            2,
            "Action create",
            wski18n.T("An action name and action are required.")); whiskErr != nil {
                return whiskErr
        }

        if action, err = parseAction(cmd, args, false); 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. An action is optional.")); whiskErr != nil {
                return whiskErr
        }

        if action, err = parseAction(cmd, args, false); 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 parameters interface{}
        var qualifiedName QualifiedName
        var paramArgs []string

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

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

        client.Namespace = qualifiedName.namespace
        paramArgs = flags.common.param

        if len(paramArgs) > 0 {
            if parameters, err = getJSONFromStrings(paramArgs, false); err != nil {
                return getJSONFromStringsParamError(paramArgs, false, err)
            }
        }
        if flags.action.result {flags.common.blocking = true}

        res, _, err := client.Actions.Invoke(
            qualifiedName.entityName,
            parameters,
            flags.common.blocking,
            flags.action.result)

        return handleInvocationResponse(qualifiedName, parameters, res, err)
    },
}

func handleInvocationResponse(
    qualifiedName QualifiedName,
    parameters interface{},
    result map[string]interface{},
    err error) (error) {
        if err == nil {
            printInvocationMsg(
                qualifiedName.namespace,
                qualifiedName.entityName,
                getValueFromJSONResponse(ACTIVATION_ID, result),
                result,
                color.Output)
        } else {
            if !flags.common.blocking {
                return handleInvocationError(err, qualifiedName.entityName, parameters)
            } else {
                if isBlockingTimeout(err) {
                    printBlockingTimeoutMsg(
                        qualifiedName.namespace,
                        qualifiedName.entityName,
                        getValueFromJSONResponse(ACTIVATION_ID, result))
                } else if isApplicationError(err) {
                    printInvocationMsg(
                        qualifiedName.namespace,
                        qualifiedName.entityName,
                        getValueFromJSONResponse(ACTIVATION_ID, result),
                        result,
                        colorable.NewColorableStderr())
                } else {
                    return handleInvocationError(err, qualifiedName.entityName, parameters)
                }
            }
        }

        return err
}

var actionGetCmd = &cobra.Command{
    Use:           "get ACTION_NAME [FIELD_FILTER]",
    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 QualifiedName

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

        if len(args) > 1 {
            field = args[1]

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

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

        client.Namespace = qualifiedName.namespace

        if action, _, err = client.Actions.Get(qualifiedName.entityName); err != nil {
            return actionGetError(qualifiedName.entityName, err)
        }

        if flags.common.summary {
            printSummary(action)
        } else {
            if len(field) > 0 {
                printActionGetWithField(qualifiedName.entityName, field, action)
            } else {
                printActionGet(qualifiedName.entityName, 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 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 = parseQualifiedName(args[0]); err != nil {
            return parseQualifiedNameError(args[0], err)
        }

        client.Namespace = qualifiedName.namespace

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

        printActionDeleted(qualifiedName.entityName)

        return nil
    },
}

var actionListCmd = &cobra.Command{
    Use:           "list [NAMESPACE]",
    Short:         wski18n.T("list all actions"),
    SilenceUsage:  true,
    SilenceErrors: true,
    PreRunE:       setupClientConfig,
    RunE: func(cmd *cobra.Command, args []string) error {
        var qualifiedName QualifiedName
        var actions []whisk.Action
        var err error

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

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

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

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

        printList(actions)

        return nil
    },
}

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

    qualifiedName := QualifiedName{}

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

    if len(args) == 2 {
        artifact = args[1]
    }

    client.Namespace = qualifiedName.namespace
    action := new(whisk.Action)
    action.Name = qualifiedName.entityName
    action.Namespace = qualifiedName.namespace
    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 flags.action.copy {
        copiedQualifiedName := QualifiedName{}

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

        client.Namespace = copiedQualifiedName.namespace

        if existingAction, _, err = client.Actions.Get(copiedQualifiedName.entityName); err != nil {
            return nil, actionGetError(copiedQualifiedName.entityName, err)
        }

        client.Namespace = qualifiedName.namespace
        action.Exec = existingAction.Exec
        action.Parameters = append(action.Parameters, existingAction.Parameters...)
        action.Annotations = append(action.Annotations, existingAction.Annotations...)
    } else if flags.action.sequence {
        action.Exec = new(whisk.Exec)
        action.Exec.Kind = "sequence"
        action.Exec.Components = csvToQualifiedActions(artifact)
    } else if len(artifact) > 0 {
        action.Exec, err = getExec(args[1], flags.action.kind, flags.action.docker, flags.action.main)
    }

    if cmd.LocalFlags().Changed(WEB_FLAG) {
        action.Annotations, err = webAction(flags.action.web, action.Annotations, qualifiedName.entityName, update)
    }

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

    return action, err
}

func getExec(artifact string, kind string, isDocker bool, mainEntry string) (*whisk.Exec, error) {
    var err error
    var code string
    var exec *whisk.Exec

    ext := filepath.Ext(artifact)
    exec = new(whisk.Exec)

    if !isDocker || ext == ".zip" {
        code, err = readFile(artifact)

        if ext == ".zip" || ext == ".jar" {
            // Base64 encode the file
            code = base64.StdEncoding.EncodeToString([]byte(code))
            exec.Code = &code
        } else {
            exec.Code = &code
        }

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

    if len(kind) > 0 {
        exec.Kind = kind
    } else if isDocker {
        exec.Kind = "blackbox"
        if ext != ".zip" {
            exec.Image = artifact
        } else {
            exec.Image = "openwhisk/dockerskeleton"
        }
    } else if ext == ".swift" {
        exec.Kind = "swift:default"
    } else if ext == ".js" {
        exec.Kind = "nodejs:default"
    } else if ext == ".py" {
        exec.Kind = "python:default"
    } else if ext == ".jar" {
        exec.Kind = "java:default"
    } else {
        if ext == ".zip" {
            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 webAction(webMode string, annotations whisk.KeyValueArr, entityName string, fetch bool) (whisk.KeyValueArr, error){
    switch strings.ToLower(webMode) {
    case "yes":
        fallthrough
    case "true":
        return webActionAnnotations(fetch, annotations, entityName, addWebAnnotations)
    case "no":
        fallthrough
    case "false":
        return webActionAnnotations(fetch, annotations, entityName, deleteWebAnnotations)
    case "raw":
        return webActionAnnotations(fetch, annotations, entityName, addRawAnnotations)
    default:
        return nil, webInputError(webMode)
    }
}

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

func webActionAnnotations(
    fetchAnnotations bool,
    annotations whisk.KeyValueArr,
    entityName string,
    webActionAnnotationMethod WebActionAnnotationMethod) (whisk.KeyValueArr, error) {
        var action *whisk.Action
        var err error

        if annotations != nil || !fetchAnnotations {
            annotations = webActionAnnotationMethod(annotations)
        } else {
            if action, _, err = client.Actions.Get(entityName); err != nil {
                return nil, actionGetError(entityName, err)
            } else {
                annotations = webActionAnnotationMethod(action.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 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.EXITCODE_ERR_GENERAL,
        whisk.DISPLAY_MSG,
        whisk.DISPLAY_USAGE)
}

func nonNestedError(errorMessage string) (error) {
    return whisk.MakeWskError(
        errors.New(errorMessage),
        whisk.EXITCODE_ERR_GENERAL,
        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(
        "Unable to parse action command arguments: {{.err}}",
        map[string]interface{}{
            "err": 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 parseQualifiedNameError(entityName string, err error) (error) {
    whisk.Debug(whisk.DbgError, "parseQualifiedName(%s) failed: %s\n", entityName, err)

    errMsg := wski18n.T(
        "'{{.name}}' is not a valid qualified name: {{.err}}",
        map[string]interface{}{
            "name": entityName,
            "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, err error) (error) {
    whisk.Debug(whisk.DbgError, "client.Actions.Get(%s) error: %s\n", entityName, 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, parameters interface{}) (error) {
    whisk.Debug(
        whisk.DbgError,
        "client.Actions.Invoke(%s, %s, %t) error: %s\n",
        entityName, parameters,
        flags.common.blocking,
        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 zipKindError() (error) {
    errMsg := wski18n.T("creating an action from a .zip artifact requires specifying the action kind explicitly")

    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 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(
    namespace string,
    entityName string,
    activationID interface{},
    response map[string]interface{},
    outputStream io.Writer) {
        if !flags.action.result {
            fmt.Fprintf(
                outputStream,
                wski18n.T(
                    "{{.ok}} invoked /{{.namespace}}/{{.name}} with id {{.id}}\n",
                    map[string]interface{}{
                        "ok": color.GreenString("ok:"),
                        "namespace": boldString(namespace),
                        "name": boldString(entityName),
                        "id": boldString(activationID),
                    }))
        }

        if flags.common.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 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),
            }))
}

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

    savedNs := client.Namespace
    client.Namespace = qname.namespace
    fullActionName := "/" + qname.namespace + "/" + qname.entityName

    action, _, err := client.Actions.Get(qname.entityName)
    if err != nil {
        whisk.Debug(whisk.DbgError, "client.Actions.Get(%s) error: %s\n", fullActionName, err)
        whisk.Debug(whisk.DbgError, "Unable to obtain action '%s' for web action validation\n", fullActionName)
        err = errors.New(wski18n.T("API action does not exist"))
    } else {
        err = errors.New(wski18n.T("API 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}))
        weVal := getValue(action.Annotations, "web-export")
        if (weVal == nil) {
            whisk.Debug(whisk.DbgError, "getValue(annotations, web-export) for action %s found no value\n", fullActionName)
        } else {
            var webExport bool
            var ok bool
            if webExport, ok = weVal.(bool); !ok {
                whisk.Debug(whisk.DbgError, "web-export annotation value (%v) is not a boolean\n", weVal)
            } else if !webExport {
                whisk.Debug(whisk.DbgError, "web-export annotation value is false\n", weVal)
            } else {
                err = nil
            }
        }
    }

    client.Namespace = savedNs
    return err
}

func init() {
    actionCreateCmd.Flags().BoolVar(&flags.action.docker, "docker", false, wski18n.T("treat ACTION as docker image path on dockerhub"))
    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", "t", TIMEOUT_LIMIT, wski18n.T("the timeout `LIMIT` in milliseconds after which the action is terminated"))
    actionCreateCmd.Flags().IntVarP(&flags.action.memory, "memory", "m", MEMORY_LIMIT, wski18n.T("the maximum memory `LIMIT` in MB for the action"))
    actionCreateCmd.Flags().IntVarP(&flags.action.logsize, "logsize", "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", "", 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().BoolVar(&flags.action.docker, "docker", false, wski18n.T("treat ACTION as docker image path on dockerhub"))
    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", "t", TIMEOUT_LIMIT, wski18n.T("the timeout `LIMIT` in milliseconds after which the action is terminated"))
    actionUpdateCmd.Flags().IntVarP(&flags.action.memory, "memory", "m", MEMORY_LIMIT, wski18n.T("the maximum memory `LIMIT` in MB for the action"))
    actionUpdateCmd.Flags().IntVarP(&flags.action.logsize, "logsize", "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", "", 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"))

    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"))

    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"))

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