/*
 * 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"
	"net/http"
	"os"
	"runtime"

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

	"github.com/spf13/cobra"
)

var Client *whisk.Client

const DefaultOpenWhiskApiPath string = "/api"

var UserAgent string = "OpenWhisk-CLI"
var AdditionalHeaders http.Header

func SetupClientConfig(cmd *cobra.Command, args []string) error {
	baseURL, err := whisk.GetURLBase(Properties.APIHost, DefaultOpenWhiskApiPath)

	// Determine if the parent command will require the API host to be set
	apiHostRequired := (cmd.Parent().Name() == "property" && cmd.Name() == "get" && (Flags.property.auth ||
		Flags.property.cert || Flags.property.key || Flags.property.apihost || Flags.property.namespace ||
		Flags.property.apiversion || Flags.property.cliversion)) ||
		(cmd.Parent().Name() == "property" && cmd.Name() == "set" && (len(Flags.property.apihostSet) > 0 ||
			len(Flags.property.apiversionSet) > 0 || len(Flags.Global.Auth) > 0)) ||
		(cmd.Parent().Name() == "sdk" && cmd.Name() == "install" && len(args) > 0 && args[0] == "bashauto")

	// Display an error if the parent command requires an API host to be set, and the current API host is not valid
	if err != nil && !apiHostRequired {
		whisk.Debug(whisk.DbgError, "whisk.GetURLBase(%s, %s) error: %s\n", Properties.APIHost, DefaultOpenWhiskApiPath, err)
		errMsg := wski18n.T("The API host is not valid: {{.err}}", map[string]interface{}{"err": err})
		whiskErr := whisk.MakeWskErrorFromWskError(errors.New(errMsg), err, whisk.EXIT_CODE_ERR_GENERAL,
			whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE)
		return whiskErr
	}

	clientConfig := &whisk.Config{
		Cert:              Properties.Cert,
		Key:               Properties.Key,
		AuthToken:         Properties.Auth,
		Namespace:         Properties.Namespace,
		BaseURL:           baseURL,
		Version:           Properties.APIVersion,
		Insecure:          Flags.Global.Insecure,
		Host:              Properties.APIHost,
		UserAgent:         UserAgent + "/1.0 (" + Properties.CLIVersion + ") " + runtime.GOOS + " " + runtime.GOARCH,
		AdditionalHeaders: AdditionalHeaders,
	}

	if len(clientConfig.Host) == 0 {
		config, _ := whisk.GetDefaultConfig()
		clientConfig.Host = config.Host
		if len(clientConfig.Host) == 0 {
			clientConfig.Host = "openwhisk.ng.bluemix.net"
		}
	}

	// Setup client
	Client, err = whisk.NewClient(http.DefaultClient, clientConfig)

	if err != nil {
		whisk.Debug(whisk.DbgError, "whisk.NewClient(%#v, %#v) error: %s\n", http.DefaultClient, clientConfig, err)
		errMsg := wski18n.T("Unable to initialize server connection: {{.err}}", map[string]interface{}{"err": err})
		whiskErr := whisk.MakeWskErrorFromWskError(errors.New(errMsg), err, whisk.EXIT_CODE_ERR_GENERAL,
			whisk.DISPLAY_MSG, whisk.DISPLAY_USAGE)
		return whiskErr
	}

	return nil
}

func init() {}

func getKeyValueArgs(args []string, argIndex int, parsedArgs []string) ([]string, []string, error) {
	var whiskErr error
	var key string
	var value string

	if len(args)-1 >= argIndex+2 {
		key = args[argIndex+1]
		value = args[argIndex+2]
		parsedArgs = append(parsedArgs, getFormattedJSON(key, value))
		args = append(args[:argIndex], args[argIndex+3:]...)
	} else {
		whisk.Debug(whisk.DbgError, "Arguments for '%s' must be a key/value pair; args: %s", args[argIndex], args)
		errMsg := wski18n.T("Arguments for '{{.arg}}' must be a key/value pair",
			map[string]interface{}{"arg": args[argIndex]})
		whiskErr = whisk.MakeWskError(errors.New(errMsg), whisk.EXIT_CODE_ERR_GENERAL, whisk.DISPLAY_MSG,
			whisk.DISPLAY_USAGE)
	}

	return parsedArgs, args, whiskErr
}

func getValueFromArgs(args []string, argIndex int, parsedArgs []string) ([]string, []string, error) {
	var whiskErr error

	if len(args)-1 >= argIndex+1 {
		parsedArgs = append(parsedArgs, args[argIndex+1])
		args = append(args[:argIndex], args[argIndex+2:]...)
	} else {
		whisk.Debug(whisk.DbgError, "An argument must be provided for '%s'; args: %s", args[argIndex], args)
		errMsg := wski18n.T("An argument must be provided for '{{.arg}}'",
			map[string]interface{}{"arg": args[argIndex]})
		whiskErr = whisk.MakeWskError(errors.New(errMsg), whisk.EXIT_CODE_ERR_GENERAL, whisk.DISPLAY_MSG,
			whisk.DISPLAY_USAGE)
	}

	return parsedArgs, args, whiskErr
}

func parseArgs(args []string) ([]string, []string, []string, error) {
	var paramArgs []string
	var annotArgs []string
	var whiskErr error

	i := 0

	for i < len(args) {
		if args[i] == "-P" || args[i] == "--param-file" {
			paramArgs, args, whiskErr = getValueFromArgs(args, i, paramArgs)
			if whiskErr != nil {
				whisk.Debug(whisk.DbgError, "getValueFromArgs(%#v, %d) failed: %s\n", args, i, whiskErr)
				errMsg := wski18n.T("The parameter arguments are invalid: {{.err}}",
					map[string]interface{}{"err": whiskErr})
				whiskErr = whisk.MakeWskError(errors.New(errMsg), whisk.EXIT_CODE_ERR_GENERAL, whisk.DISPLAY_MSG,
					whisk.DISPLAY_USAGE)
				return nil, nil, nil, whiskErr
			}

			filename := paramArgs[len(paramArgs)-1]
			paramArgs[len(paramArgs)-1], whiskErr = ReadFile(filename)
			if whiskErr != nil {
				whisk.Debug(whisk.DbgError, "readFile(%s) error: %s\n", filename, whiskErr)
				return nil, nil, nil, whiskErr
			}
		} else if args[i] == "-A" || args[i] == "--annotation-file" {
			annotArgs, args, whiskErr = getValueFromArgs(args, i, annotArgs)
			if whiskErr != nil {
				whisk.Debug(whisk.DbgError, "getValueFromArgs(%#v, %d) failed: %s\n", args, i, whiskErr)
				errMsg := wski18n.T("The annotation arguments are invalid: {{.err}}",
					map[string]interface{}{"err": whiskErr})
				whiskErr = whisk.MakeWskError(errors.New(errMsg), whisk.EXIT_CODE_ERR_GENERAL, whisk.DISPLAY_MSG,
					whisk.DISPLAY_USAGE)
				return nil, nil, nil, whiskErr
			}

			filename := annotArgs[len(annotArgs)-1]
			annotArgs[len(annotArgs)-1], whiskErr = ReadFile(filename)
			if whiskErr != nil {
				whisk.Debug(whisk.DbgError, "readFile(%s) error: %s\n", filename, whiskErr)
				return nil, nil, nil, whiskErr
			}
		} else if args[i] == "-p" || args[i] == "--param" {
			paramArgs, args, whiskErr = getKeyValueArgs(args, i, paramArgs)
			if whiskErr != nil {
				whisk.Debug(whisk.DbgError, "getKeyValueArgs(%#v, %d) failed: %s\n", args, i, whiskErr)
				errMsg := wski18n.T("The parameter arguments are invalid: {{.err}}",
					map[string]interface{}{"err": whiskErr})
				whiskErr = whisk.MakeWskError(errors.New(errMsg), whisk.EXIT_CODE_ERR_GENERAL, whisk.DISPLAY_MSG,
					whisk.DISPLAY_USAGE)
				return nil, nil, nil, whiskErr
			}
		} else if args[i] == "-a" || args[i] == "--annotation" {
			annotArgs, args, whiskErr = getKeyValueArgs(args, i, annotArgs)
			if whiskErr != nil {
				whisk.Debug(whisk.DbgError, "getKeyValueArgs(%#v, %d) failed: %s\n", args, i, whiskErr)
				errMsg := wski18n.T("The annotation arguments are invalid: {{.err}}",
					map[string]interface{}{"err": whiskErr})
				whiskErr = whisk.MakeWskError(errors.New(errMsg), whisk.EXIT_CODE_ERR_GENERAL, whisk.DISPLAY_MSG,
					whisk.DISPLAY_USAGE)
				return nil, nil, nil, whiskErr
			}
		} else {
			i++
		}
	}

	whisk.Debug(whisk.DbgInfo, "Found param args '%s'.\n", paramArgs)
	whisk.Debug(whisk.DbgInfo, "Found annotations args '%s'.\n", annotArgs)
	whisk.Debug(whisk.DbgInfo, "Arguments with param args removed '%s'.\n", args)

	return args, paramArgs, annotArgs, nil
}

func Execute() error {
	var err error

	whisk.Debug(whisk.DbgInfo, "wsk args: %#v\n", os.Args)
	os.Args, Flags.common.param, Flags.common.annotation, err = parseArgs(os.Args)

	if err != nil {
		whisk.Debug(whisk.DbgError, "parseParams(%s) failed: %s\n", os.Args, err)
		errMsg := wski18n.T("Failed to parse arguments: {{.err}}", map[string]interface{}{"err": err})
		whiskErr := whisk.MakeWskErrorFromWskError(errors.New(errMsg), err, whisk.EXIT_CODE_ERR_GENERAL,
			whisk.DISPLAY_MSG, whisk.DISPLAY_USAGE)
		return whiskErr
	}

	err = loadProperties()
	if err != nil {
		whisk.Debug(whisk.DbgError, "loadProperties() error: %s\n", err)
		errMsg := wski18n.T("Unable to access configuration properties: {{.err}}", map[string]interface{}{"err": err})
		whiskErr := whisk.MakeWskErrorFromWskError(errors.New(errMsg), err, whisk.EXIT_CODE_ERR_GENERAL,
			whisk.DISPLAY_MSG, whisk.DISPLAY_USAGE)
		return whiskErr
	}

	return WskCmd.Execute()
}
