/*
 * 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 (
	"errors"
	"fmt"
	"os"
	"os/signal"
	"strconv"
	"syscall"
	"time"

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

	"github.com/fatih/color"
	"github.com/spf13/cobra"
)

const (
	PollInterval             = time.Second * 2
	Delay                    = time.Second * 5
	MAX_ACTIVATION_LIMIT     = 200
	DEFAULT_ACTIVATION_LIMIT = 30
)

var activationCmd = &cobra.Command{
	Use:   "activation",
	Short: wski18n.T("work with activations"),
}

var activationListCmd = &cobra.Command{
	Use:           "list [NAMESPACE or NAME]",
	Short:         wski18n.T("list activations"),
	SilenceUsage:  true,
	SilenceErrors: true,
	PreRunE:       SetupClientConfig,
	RunE: func(cmd *cobra.Command, args []string) error {
		var err error
		var qualifiedName = new(QualifiedName)
		var orderedFilteredRow []whisk.ActivationFilteredRow

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

		// Specifying an activation item name filter is optional
		if len(args) == 1 {
			whisk.Debug(whisk.DbgInfo, "Activation item name filter '%s' provided\n", args[0])

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

			Client.Namespace = qualifiedName.GetNamespace()
		}

		options := &whisk.ActivationListOptions{
			Name:  qualifiedName.GetEntityName(),
			Limit: Flags.common.limit,
			Skip:  Flags.common.skip,
			Upto:  Flags.activation.upto,
			Since: Flags.activation.since,
			Docs:  Flags.common.full,
		}

		activations, _, err := Client.Activations.List(options)
		if err != nil {
			whisk.Debug(whisk.DbgError, "Client.Activations.List() error: %s\n", err)
			errStr := wski18n.T("Unable to obtain the list of activations for namespace '{{.name}}': {{.err}}",
				map[string]interface{}{"name": getClientNamespace(), "err": err})
			werr := whisk.MakeWskErrorFromWskError(errors.New(errStr), err, whisk.EXIT_CODE_ERR_GENERAL,
				whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE)
			return werr
		}

		// When the --full (URL contains "?docs=true") option is specified, display the entire activation details
		if options.Docs == true {
			printFullActivationList(activations)
		} else {
			maxKindSize := max(len("Kind"), getLargestKindSize(activations))
			maxStatusSize := max(len("Status"), getLargestStatusSize(activations))

			// Header string should show "Datetime", "Activation ID", "Kind", "Start", "Duration", "Status", "Entity", with Kind and Status being
			// dynamically sized. The last column Entity will be sized correctly when printed, so no need to calculate size here
			headerFmt := "%-19s %-32s %-" + strconv.Itoa(maxKindSize) + "s %-6s%-10s %-" + strconv.Itoa(maxStatusSize) + "s %-6s\n"
			rowFmt := "%d-%02d-%02d %02d:%02d:%02d %-32s %-" + strconv.Itoa(maxKindSize) + "s %-5s %-10v %-" + strconv.Itoa(maxStatusSize) + "s %-"

			for i := 0; i < len(activations); i++ {
				orderedFilteredRow = append(orderedFilteredRow, whisk.ActivationFilteredRow{Row: activations[i], HeaderFmt: headerFmt, RowFmt: rowFmt})
			}
			printList(orderedFilteredRow, false) // Default sorting for Activations are by creation time, hence sortByName is always false
		}

		return nil
	},
}

var activationGetCmd = &cobra.Command{
	Use:           "get (ACTIVATION_ID | --last) [FIELD_FILTER]",
	Short:         wski18n.T("get activation"),
	SilenceUsage:  true,
	SilenceErrors: true,
	PreRunE:       SetupClientConfig,
	RunE: func(cmd *cobra.Command, args []string) error {
		var field string
		var err error

		if args, err = lastFlag(args); err != nil { // Checks if any errors occurred in lastFlag(args)
			whisk.Debug(whisk.DbgError, "lastFlag(%#v) failed: %s\n", args, err)
			errStr := wski18n.T("Unable to get activation: {{.err}}",
				map[string]interface{}{"err": err})
			werr := whisk.MakeWskErrorFromWskError(errors.New(errStr), err, whisk.EXIT_CODE_ERR_GENERAL, whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE)
			return werr
		}
		if whiskErr := CheckArgs(args, 1, 2, "Activation get",
			wski18n.T("An activation ID is required.")); whiskErr != nil {
			return whiskErr
		}

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

			if !fieldExists(&whisk.Activation{}, field) {
				errMsg := wski18n.T("Invalid field filter '{{.arg}}'.", map[string]interface{}{"arg": field})
				whiskErr := whisk.MakeWskError(errors.New(errMsg), whisk.EXIT_CODE_ERR_GENERAL,
					whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE)
				return whiskErr
			}
		}

		id := args[0]
		activation, _, err := Client.Activations.Get(id)
		if err != nil {
			whisk.Debug(whisk.DbgError, "Client.Activations.Get(%s) failed: %s\n", id, err)
			errStr := wski18n.T("Unable to get activation '{{.id}}': {{.err}}",
				map[string]interface{}{"id": id, "err": err})
			werr := whisk.MakeWskErrorFromWskError(errors.New(errStr), err, whisk.EXIT_CODE_ERR_GENERAL, whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE)
			return werr
		}

		if Flags.common.summary {
			fmt.Printf(
				wski18n.T("activation result for '/{{.namespace}}/{{.name}}' ({{.status}} at {{.time}})\n",
					map[string]interface{}{
						"namespace": activation.Namespace,
						"name":      activation.Name,
						"status":    activation.Response.Status,
						"time":      time.Unix(activation.End/1000, 0)}))
			printJSON(activation.Response.Result)
		} else {

			if len(field) > 0 {
				fmt.Fprintf(color.Output,
					wski18n.T("{{.ok}} got activation {{.id}}, displaying field {{.field}}\n",
						map[string]interface{}{"ok": color.GreenString("ok:"), "id": boldString(id),
							"field": boldString(field)}))
				printField(activation, field)
			} else {
				fmt.Fprintf(color.Output, wski18n.T("{{.ok}} got activation {{.id}}\n",
					map[string]interface{}{"ok": color.GreenString("ok:"), "id": boldString(id)}))
				printJSON(activation)
			}
		}

		return nil
	},
}

var activationLogsCmd = &cobra.Command{
	Use:           "logs (ACTIVATION_ID | --last)",
	Short:         wski18n.T("get the logs of an activation"),
	SilenceUsage:  true,
	SilenceErrors: true,
	PreRunE:       SetupClientConfig,
	RunE: func(cmd *cobra.Command, args []string) error {
		var err error

		if args, err = lastFlag(args); err != nil { // Checks if any errors occurred in lastFlag(args)
			whisk.Debug(whisk.DbgError, "lastFlag(%#v) failed: %s\n", args, err)
			errStr := wski18n.T("Unable to get logs for activation: {{.err}}",
				map[string]interface{}{"err": err})
			werr := whisk.MakeWskErrorFromWskError(errors.New(errStr), err, whisk.EXIT_CODE_ERR_GENERAL, whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE)
			return werr
		}
		if whiskErr := CheckArgs(args, 1, 1, "Activation logs",
			wski18n.T("An activation ID is required.")); whiskErr != nil {
			return whiskErr
		}

		id := args[0]
		activation, _, err := Client.Activations.Logs(id)
		if err != nil {
			whisk.Debug(whisk.DbgError, "Client.Activations.Logs(%s) failed: %s\n", id, err)
			errStr := wski18n.T("Unable to get logs for activation '{{.id}}': {{.err}}",
				map[string]interface{}{"id": id, "err": err})
			werr := whisk.MakeWskErrorFromWskError(errors.New(errStr), err, whisk.EXIT_CODE_ERR_GENERAL, whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE)
			return werr
		}

		if !Flags.activation.strip {
			printActivationLogs(activation.Logs)
		} else {
			printStrippedActivationLogs(activation.Logs)
		}

		return nil
	},
}

var activationResultCmd = &cobra.Command{
	Use:           "result (ACTIVATION_ID | --last)",
	Short:         "get the result of an activation",
	SilenceUsage:  true,
	SilenceErrors: true,
	PreRunE:       SetupClientConfig,
	RunE: func(cmd *cobra.Command, args []string) error {
		var err error

		if args, err = lastFlag(args); err != nil { // Checks if any errors occurred in lastFlag(args)
			whisk.Debug(whisk.DbgError, "lastFlag(%#v) failed: %s\n", args, err)
			errStr := wski18n.T("Unable to get result for activation: {{.err}}",
				map[string]interface{}{"err": err})
			werr := whisk.MakeWskErrorFromWskError(errors.New(errStr), err, whisk.EXIT_CODE_ERR_GENERAL, whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE)
			return werr
		}
		if whiskErr := CheckArgs(args, 1, 1, "Activation result",
			wski18n.T("An activation ID is required.")); whiskErr != nil {
			return whiskErr
		}

		id := args[0]
		result, _, err := Client.Activations.Result(id)
		if err != nil {
			whisk.Debug(whisk.DbgError, "Client.Activations.result(%s) failed: %s\n", id, err)
			errStr := wski18n.T("Unable to get result for activation '{{.id}}': {{.err}}",
				map[string]interface{}{"id": id, "err": err})
			werr := whisk.MakeWskErrorFromWskError(errors.New(errStr), err, whisk.EXIT_CODE_ERR_GENERAL, whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE)
			return werr
		}

		printJSON(result.Result)
		return nil
	},
}

// lastFlag(args) retrieves the last activation with flag -l or --last
// Param: Brings in []strings from args
// Return: Returns a []string with the latest ID or the original args and any errors
func lastFlag(args []string) ([]string, error) {
	if Flags.activation.last {
		options := &whisk.ActivationListOptions{
			Limit: 1,
			Skip:  0,
		}
		activations, _, err := Client.Activations.List(options)
		if err != nil { // Checks Activations.List for errors when retrieving latest activaiton
			whisk.Debug(whisk.DbgError, "Client.Activations.List(%#v) error during lastFlag: %s\n", options, err)
			return args, err
		}
		if len(activations) == 0 { // Checks to to see if there are activations available
			whisk.Debug(whisk.DbgError, "No activations found in activation list\n")
			errStr := wski18n.T("Activation list does not contain any activations.")
			whiskErr := whisk.MakeWskError(errors.New(errStr), whisk.EXIT_CODE_ERR_GENERAL, whisk.DISPLAY_MSG, whisk.DISPLAY_USAGE)
			return args, whiskErr
		}
		if len(args) == 0 {
			whisk.Debug(whisk.DbgInfo, "Appending most recent activation ID(%s) into args\n", activations[0].ActivationID)
			args = append(args, activations[0].ActivationID)
		} else {
			whisk.Debug(whisk.DbgInfo, "Appending most recent activation ID(%s) into args\n", activations[0].ActivationID)
			args = append(args, activations[0].ActivationID)
			whisk.Debug(whisk.DbgInfo, "Allocating appended ID to correct position in args\n")
			args[0], args[len(args)-1] = args[len(args)-1], args[0] // IDs should be located at args[0], if 1 or more arguments are given ID has to be moved to args[0]
		}
	}
	return args, nil
}

var activationPollCmd = &cobra.Command{
	Use:           "poll [ NAMESPACE | ACTION_NAME ]",
	Short:         wski18n.T("poll continuously for log messages from currently running actions"),
	SilenceUsage:  true,
	SilenceErrors: true,
	PreRunE:       SetupClientConfig,
	RunE: func(cmd *cobra.Command, args []string) error {
		var name string
		var pollSince int64 // Represents an instant in time (in milliseconds since Jan 1 1970)

		if len(args) == 1 {
			name = args[0]
		} else if whiskErr := CheckArgs(args, 0, 1, "Activation poll",
			wski18n.T("An optional namespace is the only valid argument.")); whiskErr != nil {
			return whiskErr
		}

		c := make(chan os.Signal, 1)
		signal.Notify(c, os.Interrupt)
		signal.Notify(c, syscall.SIGTERM)
		go func() {
			<-c
			fmt.Println(wski18n.T("Poll terminated"))
			os.Exit(1)
		}()
		fmt.Println(wski18n.T("Enter Ctrl-c to exit."))

		// Map used to track activation records already displayed to the console
		reported := make(map[string]bool)

		if Flags.activation.sinceSeconds+
			Flags.activation.sinceMinutes+
			Flags.activation.sinceHours+
			Flags.activation.sinceDays ==
			0 {
			options := &whisk.ActivationListOptions{
				Limit: 1,
				Docs:  true,
			}
			activationList, _, err := Client.Activations.List(options)
			if err != nil {
				whisk.Debug(whisk.DbgWarn, "Client.Activations.List() error: %s\n", err)
				whisk.Debug(whisk.DbgWarn, "Ignoring Client.Activations.List failure; polling for activations since 'now'\n")
				pollSince = time.Now().Unix() * 1000 // Convert to milliseconds
			} else {
				if len(activationList) > 0 {
					lastActivation := activationList[0]  // Activation.Start is in milliseconds since Jan 1 1970
					pollSince = lastActivation.Start + 1 // Use it's start time as the basis of the polling
				}
			}
		} else {
			pollSince = time.Now().Unix() * 1000 // Convert to milliseconds

			// ParseDuration takes a string like "2h45m15s"; create this duration string from the command arguments
			durationStr := fmt.Sprintf("%dh%dm%ds",
				Flags.activation.sinceHours+Flags.activation.sinceDays*24,
				Flags.activation.sinceMinutes,
				Flags.activation.sinceSeconds,
			)
			duration, err := time.ParseDuration(durationStr)
			if err == nil {
				pollSince = pollSince - duration.Nanoseconds()/1000/1000 // Convert to milliseconds
			} else {
				whisk.Debug(whisk.DbgError, "time.ParseDuration(%s) failure: %s\n", durationStr, err)
			}
		}

		fmt.Printf(wski18n.T("Polling for activation logs\n"))
		whisk.Verbose("Polling starts from %s\n", time.Unix(pollSince/1000, 0))
		localStartTime := time.Now()

		// Polling loop
		for {
			if Flags.activation.exit > 0 {
				localDuration := time.Since(localStartTime)
				if int(localDuration.Seconds()) > Flags.activation.exit {
					whisk.Debug(whisk.DbgInfo, "Poll time (%d seconds) expired; polling loop stopped\n", Flags.activation.exit)
					return nil
				}
			}
			whisk.Verbose("Polling for activations since %s\n", time.Unix(pollSince/1000, 0))
			options := &whisk.ActivationListOptions{
				Name:  name,
				Since: pollSince,
				Docs:  true,
				Limit: 0,
				Skip:  0,
			}

			activations, _, err := Client.Activations.List(options)
			if err != nil {
				whisk.Debug(whisk.DbgWarn, "Client.Activations.List() error: %s\n", err)
				whisk.Debug(whisk.DbgWarn, "Ignoring Client.Activations.List failure; continuing to poll for activations\n")
				continue
			}

			for _, activation := range activations {
				if reported[activation.ActivationID] == true {
					continue
				} else {
					fmt.Printf(
						wski18n.T("\nActivation: '{{.name}}' ({{.id}})\n",
							map[string]interface{}{"name": activation.Name, "id": activation.ActivationID}))
					printJSON(activation.Logs)
					reported[activation.ActivationID] = true
				}
				if activation.Start > pollSince {
					pollSince = activation.Start
				}
			}
			time.Sleep(time.Second * 2)
		}
		return nil
	},
}

// Find the size needed for the Kind column when listing activations
func getLargestKindSize(activations []whisk.Activation) int {
	var maxLen = 0
	var curLen int
	var kind interface{}

	for i := 0; i < len(activations); i++ {
		kind = activations[i].Annotations.GetValue("kind")
		if kind == nil {
			kind = "unknown"
		}
		curLen = len(kind.(string))
		if curLen > maxLen {
			maxLen = curLen
		}
	}
	return maxLen
}

// Find the size needed for the Status column when listing activations
func getLargestStatusSize(activations []whisk.Activation) int {
	// The first array in the StatusCodes variable is "success"
	var maxLen = len(whisk.StatusCodes[0])
	var curLen int

	for i := 0; i < len(activations); i++ {
		if activations[i].StatusCode > 0 && activations[i].StatusCode < len(whisk.StatusCodes) {
			curLen = len(whisk.StatusCodes[activations[i].StatusCode])
			if curLen > maxLen {
				maxLen = curLen
			}
		}
	}
	return maxLen
}

func init() {
	activationListCmd.Flags().IntVarP(&Flags.common.skip, "skip", "s", 0, wski18n.T("exclude the first `SKIP` number of activations from the result"))
	activationListCmd.Flags().IntVarP(&Flags.common.limit, "limit", "l", DEFAULT_ACTIVATION_LIMIT, wski18n.T("only return `LIMIT` number of activations from the collection with a maximum LIMIT of {{.max}} activations",
		map[string]interface{}{"max": MAX_ACTIVATION_LIMIT}))
	activationListCmd.Flags().BoolVarP(&Flags.common.full, "full", "f", false, wski18n.T("include full activation description"))
	activationListCmd.Flags().Int64Var(&Flags.activation.upto, "upto", 0, wski18n.T("return activations with timestamps earlier than `UPTO`; measured in milliseconds since Th, 01, Jan 1970"))
	activationListCmd.Flags().Int64Var(&Flags.activation.since, "since", 0, wski18n.T("return activations with timestamps later than `SINCE`; measured in milliseconds since Th, 01, Jan 1970"))

	activationGetCmd.Flags().BoolVarP(&Flags.common.summary, "summary", "s", false, wski18n.T("summarize activation details"))
	activationGetCmd.Flags().BoolVarP(&Flags.activation.last, "last", "l", false, wski18n.T("retrieves the last activation"))

	activationLogsCmd.Flags().BoolVarP(&Flags.activation.last, "last", "l", false, wski18n.T("retrieves the last activation"))
	activationLogsCmd.Flags().BoolVarP(&Flags.activation.strip, "strip", "r", false, wski18n.T("strip timestamp and stream information"))
	activationResultCmd.Flags().BoolVarP(&Flags.activation.last, "last", "l", false, wski18n.T("retrieves the last activation"))

	activationPollCmd.Flags().IntVarP(&Flags.activation.exit, "exit", "e", 0, wski18n.T("stop polling after `SECONDS` seconds"))
	activationPollCmd.Flags().IntVar(&Flags.activation.sinceSeconds, "since-seconds", 0, wski18n.T("start polling for activations `SECONDS` seconds ago"))
	activationPollCmd.Flags().IntVar(&Flags.activation.sinceMinutes, "since-minutes", 0, wski18n.T("start polling for activations `MINUTES` minutes ago"))
	activationPollCmd.Flags().IntVar(&Flags.activation.sinceHours, "since-hours", 0, wski18n.T("start polling for activations `HOURS` hours ago"))
	activationPollCmd.Flags().IntVar(&Flags.activation.sinceDays, "since-days", 0, wski18n.T("start polling for activations `DAYS` days ago"))

	activationCmd.AddCommand(
		activationListCmd,
		activationGetCmd,
		activationLogsCmd,
		activationResultCmd,
		activationPollCmd,
	)
}
