/*
 * 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"
	"io"
	"os"
	"strings"

	"github.com/spf13/cobra"

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

// sdkCmd represents the sdk command
var sdkCmd = &cobra.Command{
	Use:   "sdk",
	Short: wski18n.T("work with the sdk"),
}

type sdkInfo struct {
	UrlPath   string
	FileName  string
	isGzTar   bool
	IsGzip    bool
	IsZip     bool
	IsTar     bool
	Unpack    bool
	UnpackDir string
}

var sdkMap map[string]*sdkInfo

const SDK_DOCKER_COMPONENT_NAME string = "docker"
const SDK_IOS_COMPONENT_NAME string = "ios"
const BASH_AUTOCOMPLETE_FILENAME string = "wsk_cli_bash_completion.sh"

var sdkInstallCmd = &cobra.Command{
	Use:           "install COMPONENT",
	Short:         wski18n.T("install SDK artifacts"),
	Long:          wski18n.T("install SDK artifacts, where valid COMPONENT values are docker, ios, and bashauto"),
	SilenceUsage:  true,
	SilenceErrors: true,
	PreRunE:       SetupClientConfig,
	RunE: func(cmd *cobra.Command, args []string) error {
		var err error
		if len(args) != 1 {
			whisk.Debug(whisk.DbgError, "Invalid number of arguments: %d\n", len(args))
			errStr := wski18n.T("The SDK component argument is missing. One component (docker, ios, or bashauto) must be specified")
			werr := whisk.MakeWskError(errors.New(errStr), whisk.EXIT_CODE_ERR_GENERAL, whisk.DISPLAY_MSG, whisk.DISPLAY_USAGE)
			return werr
		}
		component := strings.ToLower(args[0])
		switch component {
		case "docker":
			err = dockerInstall()
		case "ios":
			err = iOSInstall()
		case "bashauto":
			if Flags.sdk.stdout {
				if err = WskCmd.GenBashCompletion(os.Stdout); err != nil {
					whisk.Debug(whisk.DbgError, "GenBashCompletion error: %s\n", err)
					errStr := wski18n.T("Unable to output bash command completion {{.err}}",
						map[string]interface{}{"err": err})
					werr := whisk.MakeWskError(errors.New(errStr), whisk.EXIT_CODE_ERR_GENERAL, whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE)
					return werr
				}
			} else {
				err = WskCmd.GenBashCompletionFile(BASH_AUTOCOMPLETE_FILENAME)
				if err != nil {
					whisk.Debug(whisk.DbgError, "GenBashCompletionFile('%s`) error: \n", BASH_AUTOCOMPLETE_FILENAME, err)
					errStr := wski18n.T("Unable to generate '{{.name}}': {{.err}}",
						map[string]interface{}{"name": BASH_AUTOCOMPLETE_FILENAME, "err": err})
					werr := whisk.MakeWskError(errors.New(errStr), whisk.EXIT_CODE_ERR_GENERAL, whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE)
					return werr
				}
				fmt.Printf(
					wski18n.T("bash_completion_msg",
						map[string]interface{}{"name": BASH_AUTOCOMPLETE_FILENAME}))
			}
		default:
			whisk.Debug(whisk.DbgError, "Invalid component argument '%s'\n", component)
			errStr := wski18n.T("The SDK component argument '{{.component}}' is invalid. Valid components are docker, ios and bashauto",
				map[string]interface{}{"component": component})
			err = whisk.MakeWskError(errors.New(errStr), whisk.EXIT_CODE_ERR_GENERAL, whisk.DISPLAY_MSG, whisk.DISPLAY_USAGE)
		}

		if err != nil {
			return err
		}
		return nil
	},
}

func dockerInstall() error {
	var err error

	targetFile := sdkMap[SDK_DOCKER_COMPONENT_NAME].FileName
	if _, err = os.Stat(targetFile); err == nil {
		whisk.Debug(whisk.DbgError, "os.Stat reports file '%s' exists\n", targetFile)
		errStr := wski18n.T("The file '{{.name}}' already exists.  Delete it and retry.",
			map[string]interface{}{"name": targetFile})
		werr := whisk.MakeWskError(errors.New(errStr), whisk.EXIT_CODE_ERR_GENERAL, whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE)
		return werr
	}

	if err = sdkInstall(SDK_DOCKER_COMPONENT_NAME); err != nil {
		whisk.Debug(whisk.DbgError, "sdkInstall(%s) failed: %s\n", SDK_DOCKER_COMPONENT_NAME, err)
		errStr := wski18n.T("The {{.component}} SDK installation failed: {{.err}}",
			map[string]interface{}{"component": SDK_DOCKER_COMPONENT_NAME, "err": err})
		werr := whisk.MakeWskErrorFromWskError(errors.New(errStr), err, whisk.EXIT_CODE_ERR_GENERAL, whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE)
		return werr
	}

	fmt.Println(wski18n.T("The docker skeleton is now installed at the current directory."))
	return nil
}

func iOSInstall() error {
	var err error

	if err = sdkInstall(SDK_IOS_COMPONENT_NAME); err != nil {
		whisk.Debug(whisk.DbgError, "sdkInstall(%s) failed: %s\n", SDK_IOS_COMPONENT_NAME, err)
		errStr := wski18n.T("The {{.component}} SDK installation failed: {{.err}}",
			map[string]interface{}{"component": SDK_IOS_COMPONENT_NAME, "err": err})
		werr := whisk.MakeWskErrorFromWskError(errors.New(errStr), err, whisk.EXIT_CODE_ERR_GENERAL, whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE)
		return werr
	}

	fmt.Printf(
		wski18n.T("Downloaded OpenWhisk iOS starter app. Unzip '{{.name}}' and open the project in Xcode.\n",
			map[string]interface{}{"name": sdkMap[SDK_IOS_COMPONENT_NAME].FileName}))
	return nil
}

func sdkInstall(componentName string) error {
	targetFile := sdkMap[componentName].FileName
	if _, err := os.Stat(targetFile); err == nil {
		whisk.Debug(whisk.DbgError, "os.Stat reports file '%s' exists\n", targetFile)
		errStr := wski18n.T("The file '{{.name}}' already exists.  Delete it and retry.",
			map[string]interface{}{"name": targetFile})
		werr := whisk.MakeWskError(errors.New(errStr), whisk.EXIT_CODE_ERR_GENERAL, whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE)
		return werr
	}

	resp, err := Client.Sdks.Install(sdkMap[componentName].UrlPath)
	if err != nil {
		whisk.Debug(whisk.DbgError, "Client.Sdks.Install(%s) failed: %s\n", sdkMap[componentName].UrlPath, err)
		errStr := wski18n.T("Unable to retrieve '{{.urlpath}}' SDK: {{.err}}",
			map[string]interface{}{"urlpath": sdkMap[componentName].UrlPath, "err": err})
		werr := whisk.MakeWskErrorFromWskError(errors.New(errStr), err, whisk.EXIT_CODE_ERR_GENERAL, whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE)
		return werr
	}

	if resp.Body == nil {
		whisk.Debug(whisk.DbgError, "SDK Install HTTP response has no body\n")
		errStr := wski18n.T("Server failed to send the '{{.component}}' SDK: {{.err}}",
			map[string]interface{}{"name": componentName, "err": err})
		werr := whisk.MakeWskError(errors.New(errStr), whisk.EXIT_CODE_ERR_NETWORK, whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE)
		return werr
	}

	// Create the SDK file
	sdkfile, err := os.Create(targetFile)
	if err != nil {
		whisk.Debug(whisk.DbgError, "os.Create(%s) failure: %s\n", targetFile, err)
		errStr := wski18n.T("Error creating SDK file '{{.name}}': {{.err}}",
			map[string]interface{}{"name": targetFile, "err": err})
		werr := whisk.MakeWskErrorFromWskError(errors.New(errStr), err, whisk.EXIT_CODE_ERR_GENERAL, whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE)
		return werr
	}

	// Read the HTTP response body and write it to the SDK file
	whisk.Debug(whisk.DbgInfo, "Reading SDK file from HTTP response body\n")
	_, err = io.Copy(sdkfile, resp.Body)
	if err != nil {
		whisk.Debug(whisk.DbgError, "io.Copy() of resp.Body into sdkfile failure: %s\n", err)
		errStr := wski18n.T("Error copying server response into file: {{.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)
		sdkfile.Close()
		return werr

	}
	sdkfile.Close() // Don't use 'defer' since this file might need to be deleted after unpack

	// At this point, the entire file is downloaded from the server
	// Check if there is any special post-download processing (i.e. unpack)
	if sdkMap[componentName].Unpack {
		// Make sure the target directory does not already exist
		defer os.Remove(targetFile)
		targetdir := sdkMap[componentName].UnpackDir
		if _, err = os.Stat(targetdir); err == nil {
			whisk.Debug(whisk.DbgError, "os.Stat reports that directory '%s' exists\n", targetdir)
			errStr := wski18n.T("The directory '{{.name}}' already exists.  Delete it and retry.",
				map[string]interface{}{"name": targetdir})
			werr := whisk.MakeWskError(errors.New(errStr), whisk.EXIT_CODE_ERR_GENERAL, whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE)
			return werr
		}

		// If the packed SDK is a .tgz file, unpack it in two steps
		// 1. UnGzip into temp .tar file
		// 2. Untar the contents into the current folder
		if sdkMap[componentName].isGzTar {
			whisk.Debug(whisk.DbgInfo, "unGzipping downloaded file\n")
			err := unpackGzip(targetFile, "temp.tar")
			if err != nil {
				whisk.Debug(whisk.DbgError, "unpackGzip(%s,temp.tar) failure: %s\n", targetFile, err)
				errStr := wski18n.T("Error unGzipping file '{{.name}}': {{.err}}",
					map[string]interface{}{"name": targetFile, "err": err})
				werr := whisk.MakeWskError(errors.New(errStr), whisk.EXIT_CODE_ERR_GENERAL, whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE)
				return werr
			}
			defer os.Remove("temp.tar")

			whisk.Debug(whisk.DbgInfo, "unTarring unGzipped file\n")
			err = unpackTar("temp.tar")
			if err != nil {
				whisk.Debug(whisk.DbgError, "unpackTar(temp.tar) failure: %s\n", err)
				errStr := wski18n.T("Error untarring file '{{.name}}': {{.err}}",
					map[string]interface{}{"name": "temp.tar", "err": err})
				werr := whisk.MakeWskError(errors.New(errStr), whisk.EXIT_CODE_ERR_GENERAL, whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE)
				return werr
			}
		}

		// Future SDKs may require other unpacking procedures not yet covered here....
	}

	return nil
}

func init() {
	sdkInstallCmd.Flags().BoolVarP(&Flags.sdk.stdout, "stdout", "s", false, wski18n.T("prints bash command completion script to stdout"))

	sdkCmd.AddCommand(sdkInstallCmd)

	sdkMap = make(map[string]*sdkInfo)
	sdkMap["docker"] = &sdkInfo{UrlPath: "blackbox.tar.gz", FileName: "blackbox.tar.gz", isGzTar: true, Unpack: true, UnpackDir: "dockerSkeleton"}
	sdkMap["ios"] = &sdkInfo{UrlPath: "OpenWhiskIOSStarterApp.zip", FileName: "OpenWhiskIOSStarterApp.zip", IsZip: true, Unpack: false}
}
