/*
 * 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 common

import (
	"bytes"
	"errors"
	"fmt"
	"os"
	"os/exec"
	"path"
	"path/filepath"
	"strings"
	"time"

	"github.com/apache/openwhisk-client-go/whisk"
	"github.com/apache/openwhisk-wskdeploy/dependencies"
	"github.com/apache/openwhisk-wskdeploy/deployers"
	"github.com/apache/openwhisk-wskdeploy/runtimes"
	"github.com/apache/openwhisk-wskdeploy/utils"
	"github.com/apache/openwhisk-wskdeploy/wskderrors"
	"github.com/fatih/color"
	"github.com/mattn/go-colorable"
)

const (
	cmd               = "wskdeploy"
	BLUEMIX_APIHOST   = "BLUEMIX_APIHOST"
	BLUEMIX_NAMESPACE = "BLUEMIX_NAMESPACE"
	BLUEMIX_AUTH      = "BLUEMIX_AUTH"
)

type Wskdeploy struct {
	Path string
	Dir  string
}

func NewWskdeploy() *Wskdeploy {
	return NewWskWithPath(os.Getenv("GOPATH") + "/src/github.com/apache/openwhisk-wskdeploy/")
}

func GetWskpropsFromEnvVars(apiHost string, namespace string, authKey string) *whisk.Wskprops {
	return GetWskpropsFromValues(os.Getenv(apiHost), os.Getenv(namespace), os.Getenv(authKey), "v1")
}

func GetWskpropsFromValues(apiHost string, namespace string, authKey string, version string) *whisk.Wskprops {
	dep := whisk.Wskprops{
		APIHost:        apiHost,
		AuthKey:        authKey,
		Namespace:      namespace,
		AuthAPIGWKey:   "",
		APIGWSpaceSuid: "",
		Apiversion:     version,
		Key:            "",
		Cert:           "",
		Source:         "",
	}
	return &dep
}

func ValidateWskprops(wskprops *whisk.Wskprops) error {
	if len(wskprops.APIHost) == 0 {
		return errors.New("Missing APIHost for wskprops.")
	}
	if len(wskprops.Namespace) == 0 {
		return errors.New("Missing Namespace for wskprops.")
	}
	if len(wskprops.AuthKey) == 0 {
		return errors.New("Missing AuthKey for wskprops.")
	}
	return nil
}

func NewWskWithPath(path string) *Wskdeploy {
	var dep Wskdeploy
	dep.Path = cmd
	dep.Dir = path
	return &dep
}

func printCommand(cmd *exec.Cmd) {
	fmt.Printf("==> Executing: %s\n", strings.Join(cmd.Args, " "))
}

func printError(err string) {
	outputStream := colorable.NewColorableStderr()
	if len(err) > 0 {
		fmt.Fprintf(outputStream, "==> Error: %s.\n", color.RedString(err))
	} else {
		fmt.Fprintf(outputStream, "==> Error: %s.\n", color.RedString("No error message"))
	}
}

func printOutput(outs string) {
	if len(outs) > 0 {
		fmt.Printf("==> Output: %s.\n", outs)
	}
}

func (wskdeploy *Wskdeploy) RunCommand(s ...string) (string, error) {
	command := exec.Command(wskdeploy.Path, s...)
	command.Dir = wskdeploy.Dir

	printCommand(command)

	var outb, errb bytes.Buffer
	command.Stdout = &outb
	command.Stderr = &errb
	err := command.Run()

	var returnError error = nil
	if err != nil {
		// Note: (sub-command) is always at Args[0] which is guaranteed to be not empty
		returnError = wskderrors.NewCommandError(command.Args[0], errb.String())
	}
	printOutput(outb.String())
	if returnError != nil {
		printError(returnError.Error())
	}
	return outb.String(), returnError
}

func (wskdeploy *Wskdeploy) Deploy(manifestPath string, deploymentPath string) (string, error) {
	return wskdeploy.RunCommand("-m", manifestPath, "-d", deploymentPath)
}

func (wskdeploy *Wskdeploy) DeployManifestVerbose(manifestPath string) (string, error) {
	return wskdeploy.RunCommand("-m", manifestPath, "-v")
}

func (wskdeploy *Wskdeploy) DeployWithCredentials(manifestPath string, deploymentPath string, wskprops *whisk.Wskprops) (string, error) {
	return wskdeploy.RunCommand("-m", manifestPath, "-d", deploymentPath, "--auth", wskprops.AuthKey,
		"--namespace", wskprops.Namespace, "--apihost", wskprops.APIHost, "--apiversion", wskprops.Apiversion)
}

func (wskdeploy *Wskdeploy) Undeploy(manifestPath string, deploymentPath string) (string, error) {
	return wskdeploy.RunCommand("undeploy", "-m", manifestPath, "-d", deploymentPath)
}

func (wskdeploy *Wskdeploy) UndeployWithCredentials(manifestPath string, deploymentPath string, wskprops *whisk.Wskprops) (string, error) {
	return wskdeploy.RunCommand("undeploy", "-m", manifestPath, "-d", deploymentPath, "--auth", wskprops.AuthKey,
		"--namespace", wskprops.Namespace, "--apihost", wskprops.APIHost, "--apiversion", wskprops.Apiversion)
}

func (wskdeploy *Wskdeploy) DeployProjectPathOnly(projectPath string) (string, error) {
	return wskdeploy.RunCommand("-p", projectPath)
}

func (wskdeploy *Wskdeploy) UndeployProjectPathOnly(projectPath string) (string, error) {
	return wskdeploy.RunCommand("undeploy", "-p", projectPath)

}

func (wskdeploy *Wskdeploy) DeployManifestPathOnly(manifestpath string) (string, error) {
	return wskdeploy.RunCommand("-m", manifestpath)
}

func (wskdeploy *Wskdeploy) UndeployManifestPathOnly(manifestpath string) (string, error) {
	return wskdeploy.RunCommand("undeploy", "-m", manifestpath)
}

func (Wskdeploy *Wskdeploy) ManagedDeploymentOnlyManifest(manifestPath string) (string, error) {
	return Wskdeploy.RunCommand("sync", "-m", manifestPath)
}

func (Wskdeploy *Wskdeploy) ManagedDeploymentManifestAndProject(manifestPath string, projectName string) (string, error) {
	return Wskdeploy.RunCommand("sync", "-m", manifestPath, "--projectname", projectName)
}

func (Wskdeploy *Wskdeploy) ManagedDeploymentManifestAndProjectWithCredentials(manifestPath string, projectName string, wskprops *whisk.Wskprops) (string, error) {
	return Wskdeploy.RunCommand("sync", "-m", manifestPath, "--projectname", projectName, "--auth", wskprops.AuthKey,
		"--namespace", wskprops.Namespace, "--apihost", wskprops.APIHost, "--apiversion", wskprops.Apiversion)
}

func (Wskdeploy *Wskdeploy) ManagedDeployment(manifestPath string, deploymentPath string) (string, error) {
	return Wskdeploy.RunCommand("sync", "-m", manifestPath, "-d", deploymentPath)
}

func (Wskdeploy *Wskdeploy) HeadlessManagedDeployment(manifestPath string, deploymentPath string, name string) (string, error) {
	return Wskdeploy.RunCommand("sync", "-m", manifestPath, "-d", deploymentPath, "--projectname", name)
}

// Note: this test often fails due to server-related issues trying to access
// newly created objects (e.g., primarily Rules) too quickly which often lose Annotations.
// causing SIGSEGV errors.
// It also sometimes fails accessing local storage (for tmp directories and files
// that are created in Travis (constrained, shared environments).
// You can add the "-t" or "--trace" to the RunCommand to get extensive trace on all HTTP calls
func (wskdeploy *Wskdeploy) ExportProject(projectName string, targetManifestPath string) (string, error) {
	// TODO: There is a server-side timing issue with Annotations being
	// retrieved too soon after creation; need to explore in OW main
	time.Sleep(3 * time.Second) // should it sleep for few seconds before export?!
	return wskdeploy.RunCommand("export", "-m", targetManifestPath, "--projectname", projectName)
}

func (wskdeploy *Wskdeploy) ExportProjectWithCredentials(projectName string, targetManifestPath string, wskprops *whisk.Wskprops) (string, error) {
	// TODO: There is a server-side timing issue with Annotations being
	// retrieved too soon after creation; need to explore in OW main
	time.Sleep(3 * time.Second) // should it sleep for few seconds before export?!
	return wskdeploy.RunCommand("export", "-m", targetManifestPath, "--projectname", projectName, "--auth", wskprops.AuthKey,
		"--namespace", wskprops.Namespace, "--apihost", wskprops.APIHost, "--apiversion", wskprops.Apiversion)
}

// This method is only for testing
// This method will mock a construction of deployment plan, creating all the memory objects
// This method CANNOT be used for real deployment!
// Param manifestPath & deploymentPath MUST be the absolute path.
func (wskdeploy *Wskdeploy) GetDeploymentObjects(manifestPath string, deploymentPath string) (*deployers.DeploymentProject, error) {
	//create ServiceDeployer and set default values
	deployer := deployers.NewServiceDeployer()
	deployer.ProjectPath = filepath.Dir(manifestPath)
	deployer.ManifestPath = manifestPath
	deployer.DeploymentPath = deploymentPath
	deployer.DependencyMaster = make(map[string]dependencies.DependencyRecord)

	//create client config with namespace, apihost, authkey and etc.
	//these values might be mock values because it's only for testing
	userHome := utils.GetHomeDirectory()
	defaultPath := path.Join(userHome, whisk.DEFAULT_LOCAL_CONFIG)
	clientConfig, err := deployers.NewWhiskConfig(defaultPath, deploymentPath, manifestPath)
	if err != nil {
		return nil, err
	}
	deployer.ClientConfig = clientConfig

	//setSupportedRuntimes(apiHost string)
	//only for testing, mock values
	op, err := runtimes.ParseOpenWhisk(clientConfig.Host)
	if err == nil {
		runtimes.SupportedRunTimes = runtimes.ConvertToMap(op)
		runtimes.DefaultRunTimes = runtimes.DefaultRuntimes(op)
		runtimes.FileExtensionRuntimeKindMap = runtimes.FileExtensionRuntimes(op)
	}

	//invoke ConstructDeploymentPlan to create the in memory objects for deployment
	err = deployer.ConstructDeploymentPlan()
	if err != nil {
		return nil, err
	}
	//return the deployment objects
	return deployer.Deployment, nil
}
