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

import (
	"bufio"
	"fmt"
	"os"
	"strings"
	"sync"

	"github.com/openwhisk/openwhisk-client-go/whisk"
	"github.com/openwhisk/openwhisk-wskdeploy/parsers"
	"github.com/openwhisk/openwhisk-wskdeploy/utils"
	"log"
)

type DeploymentApplication struct {
	Packages map[string]*DeploymentPackage
	Triggers map[string]*whisk.Trigger
	Rules    map[string]*whisk.Rule
}

func NewDeploymentApplication() *DeploymentApplication {
	var dep DeploymentApplication
	dep.Packages = make(map[string]*DeploymentPackage)
	dep.Triggers = make(map[string]*whisk.Trigger)
	dep.Rules = make(map[string]*whisk.Rule)
	return &dep
}

type DeploymentPackage struct {
	Package   *whisk.Package
	Actions   map[string]utils.ActionRecord
	Sequences map[string]utils.ActionRecord
}

func NewDeploymentPackage() *DeploymentPackage {
	var dep DeploymentPackage
	dep.Actions = make(map[string]utils.ActionRecord)
	dep.Sequences = make(map[string]utils.ActionRecord)
	return &dep
}

//ServiceDeployer defines a prototype service deployer.  It should do the following:
//   1. Collect information from the manifest file (if any)
//   2. Collect information from the deployment file (if any)
//   3. Collect information about the source code files in the working directory
//   4. Create a deployment plan to create OpenWhisk service
type ServiceDeployer struct {
	Deployment      *DeploymentApplication
	Client          *whisk.Client
	mt              sync.RWMutex
	RootPackageName string
	IsInteractive   bool
	IsDefault       bool
	ManifestPath    string
	ProjectPath     string
	DeploymentPath  string
	//whether to deploy the action under the package
	DeployActionInPackage bool
	InteractiveChoice     bool
	ClientConfig          *whisk.Config
}

// NewServiceDeployer is a Factory to create a new ServiceDeployer
func NewServiceDeployer() *ServiceDeployer {
	var dep ServiceDeployer
	dep.Deployment = NewDeploymentApplication()
	dep.IsInteractive = true
	dep.DeployActionInPackage = true

	return &dep
}

// Check if the manifest yaml could be parsed by Manifest Parser.
// Check if the deployment yaml could be parsed by Manifest Parser.
func (deployer *ServiceDeployer) Check() {
	ps := parsers.NewYAMLParser()
	if utils.FileExists(deployer.DeploymentPath) {
		ps.ParseDeployment(deployer.DeploymentPath)
	}
	ps.ParseManifest(deployer.ManifestPath)
	// add more schema check or manifest/deployment consistency checks here if
	// necessary
}

func (deployer *ServiceDeployer) ConstructDeploymentPlan() error {

	var manifestReader = NewManfiestReader(deployer)
	manifest, manifestParser, err := manifestReader.ParseManifest()
	utils.Check(err)

	deployer.RootPackageName = manifest.Package.Packagename

	manifestReader.InitRootPackage(manifestParser, manifest)

	if deployer.IsDefault == true && !utils.Flags.WithinOpenWhisk {
		fileReader := NewFileSystemReader(deployer)
		fileActions, err := fileReader.ReadProjectDirectory(manifest)
		utils.Check(err)

		fileReader.SetFileActions(fileActions)
	}

	// process manifest file
	err = manifestReader.HandleYaml(manifestParser, manifest)
	utils.Check(err)

	// process deploymet file
	if utils.FileExists(deployer.DeploymentPath) {
		var deploymentReader = NewDeploymentReader(deployer)
		deploymentReader.HandleYaml()

		deploymentReader.BindAssets()
	}

	return nil
}

func (deployer *ServiceDeployer) ConstructUnDeploymentPlan() (*DeploymentApplication, error) {

	var manifestReader = NewManfiestReader(deployer)
	manifest, manifestParser, err := manifestReader.ParseManifest()
	utils.Check(err)

	manifestReader.InitRootPackage(manifestParser, manifest)

	// process file system
	if deployer.IsDefault == true {
		fileReader := NewFileSystemReader(deployer)
		fileActions, err := fileReader.ReadProjectDirectory(manifest)
		utils.Check(err)

		err = fileReader.SetFileActions(fileActions)
		utils.Check(err)

	}

	// process manifest file
	err = manifestReader.HandleYaml(manifestParser, manifest)
	utils.Check(err)

	// process deploymet file
	if utils.FileExists(deployer.DeploymentPath) {
		var deploymentReader = NewDeploymentReader(deployer)
		deploymentReader.HandleYaml()

		deploymentReader.BindAssets()
	}

	verifiedPlan := deployer.Deployment

	return verifiedPlan, nil
}

// Use relfect util to deploy everything in this service deployer
// according some planning?
func (deployer *ServiceDeployer) Deploy() error {

	if deployer.IsInteractive == true && !utils.Flags.WithinOpenWhisk {
		deployer.printDeploymentAssets(deployer.Deployment)
		reader := bufio.NewReader(os.Stdin)
		fmt.Print("Do you really want to deploy this? (y/N): ")

		text, _ := reader.ReadString('\n')
		text = strings.TrimSpace(text)

		if text == "" {
			text = "n"
		}

		if strings.EqualFold(text, "y") || strings.EqualFold(text, "yes") {
			deployer.InteractiveChoice = true
			if err := deployer.deployAssets(); err != nil {
				log.Println("\nDeployment did not complete sucessfully. Run `wskdeploy undeploy` to remove partially deployed assets")
				return err
			}

			fmt.Println("\nDeployment completed successfully.")
			return nil

		} else {
			deployer.InteractiveChoice = false
			fmt.Println("OK. Cancelling deployment")
			return nil
		}
	}

	// non-interactive
	if err := deployer.deployAssets(); err != nil {
		log.Println("\nDeployment did not complete sucessfully. Run `wskdeploy undeploy` to remove partially deployed assets")
		return err
	}

	log.Println("\nDeployment completed successfully.")
	return nil

}

func (deployer *ServiceDeployer) deployAssets() error {

	if err := deployer.DeployPackages(); err != nil {
		return err
	}

	if err := deployer.DeployActions(); err != nil {
		return err
	}

	if err := deployer.DeploySequences(); err != nil {
		return err
	}

	if err := deployer.DeployTriggers(); err != nil {
		return err
	}

	if err := deployer.DeployRules(); err != nil {
		return err
	}
	return nil
}

func (deployer *ServiceDeployer) DeployPackages() error {
	for _, pack := range deployer.Deployment.Packages {
		deployer.createPackage(pack.Package)
	}
	return nil
}

// DeployActions into OpenWhisk
func (deployer *ServiceDeployer) DeploySequences() error {

	for _, pack := range deployer.Deployment.Packages {
		for _, action := range pack.Sequences {
			deployer.createAction(pack.Package.Name, action.Action)
		}
	}
	return nil
}

// DeployActions into OpenWhisk
func (deployer *ServiceDeployer) DeployActions() error {

	for _, pack := range deployer.Deployment.Packages {
		for _, action := range pack.Actions {
			err := deployer.createAction(pack.Package.Name, action.Action)
			if err != nil {
				return err
			}
		}
	}
	return nil
}

// Deploy Triggers into OpenWhisk
func (deployer *ServiceDeployer) DeployTriggers() error {
	for _, trigger := range deployer.Deployment.Triggers {

		if feedname, isFeed := utils.IsFeedAction(trigger); isFeed {
			deployer.createFeedAction(trigger, feedname)
		} else {
			deployer.createTrigger(trigger)
		}

	}
	return nil

}

// Deploy Rules into OpenWhisk
func (deployer *ServiceDeployer) DeployRules() error {
	for _, rule := range deployer.Deployment.Rules {
		deployer.createRule(rule)
	}
	return nil
}

func (deployer *ServiceDeployer) createPackage(packa *whisk.Package) {
	log.Print("Deploying package " + packa.Name + " ... ")
	_, _, err := deployer.Client.Packages.Insert(packa, true)
	if err != nil {
		wskErr := err.(*whisk.WskError)
		log.Printf("Got error creating package with error message: %v and error code: %v.\n", wskErr.Error(), wskErr.ExitCode)
	}
	log.Println("Done!")
}

func (deployer *ServiceDeployer) createTrigger(trigger *whisk.Trigger) {
	_, _, err := deployer.Client.Triggers.Insert(trigger, true)
	if err != nil {
		wskErr := err.(*whisk.WskError)
		log.Printf("Got error creating trigger with error message: %v and error code: %v.\n", wskErr.Error(), wskErr.ExitCode)
	}
	fmt.Println("Done!")
}

func (deployer *ServiceDeployer) createFeedAction(trigger *whisk.Trigger, feedName string) {
	log.Println("Deploying trigger feed " + trigger.Name + " ... ")
	// to hold and modify trigger parameters, not passed by ref?
	params := make(map[string]interface{})

	// check for strings that are JSON
	for _, keyVal := range trigger.Parameters {
		if b, isJson := utils.IsJSON(keyVal.Value.(string)); isJson {
			fmt.Println(keyVal.Key + " is JSON " + keyVal.Value.(string))
			params[keyVal.Key] = b
		} else {
			params[keyVal.Key] = keyVal.Value
		}
	}

	params["authKey"] = deployer.ClientConfig.AuthToken
	params["lifecycleEvent"] = "CREATE"
	params["triggerName"] = "/" + deployer.Client.Namespace + "/" + trigger.Name

	pub := true
	t := &whisk.Trigger{
		Name:        trigger.Name,
		Annotations: trigger.Annotations,
		Publish:     &pub,
	}

	_, _, err := deployer.Client.Triggers.Insert(t, false)
	if err != nil {
		wskErr := err.(*whisk.WskError)
		log.Printf("Got error creating trigger with error message: %v and error code: %v.\n", wskErr.Error(), wskErr.ExitCode)
	} else {

		qName, err := utils.ParseQualifiedName(feedName, deployer.ClientConfig.Namespace)

		utils.Check(err)

		namespace := deployer.Client.Namespace
		deployer.Client.Namespace = qName.Namespace
		_, _, err = deployer.Client.Actions.Invoke(qName.EntityName, params, true, false)
		deployer.Client.Namespace = namespace

		if err != nil {
			wskErr := err.(*whisk.WskError)
			log.Printf("Got error creating trigger feed with error message: %v and error code: %v.\n", wskErr.Error(), wskErr.ExitCode)
		}
	}
	fmt.Println("Done!")
}

func (deployer *ServiceDeployer) createRule(rule *whisk.Rule) {
	// The rule's trigger should include the namespace with pattern /namespace/trigger
	rule.Trigger = deployer.getQualifiedName(rule.Trigger.(string), deployer.ClientConfig.Namespace)
	// The rule's action should include the namespace and package with pattern /namespace/package/action
	// please refer https://github.com/openwhisk/openwhisk/issues/1577

	// if it contains a slash, then the action is qualified by a package name
	if strings.Contains(rule.Action.(string), "/") {
		rule.Action = deployer.getQualifiedName(rule.Action.(string), deployer.ClientConfig.Namespace)
	} else {
		// if not, we assume the action is inside the root package
		rule.Action = deployer.getQualifiedName(strings.Join([]string{deployer.RootPackageName, rule.Action.(string)}, "/"), deployer.ClientConfig.Namespace)
	}
	fmt.Print("Deploying rule " + rule.Name + " ... ")
	_, _, err := deployer.Client.Rules.Insert(rule, true)
	if err != nil {
		wskErr := err.(*whisk.WskError)
		log.Printf("Got error creating rule with error message: %v and error code: %v.\n", wskErr.Error(), wskErr.ExitCode)
	}

	_, _, err = deployer.Client.Rules.SetState(rule.Name, "active")
	if err != nil {
		wskErr := err.(*whisk.WskError)
		log.Printf("Got error activating rule with error message: %v and error code: %v.\n", wskErr.Error(), wskErr.ExitCode)
	}
	fmt.Println("Done!")
}

// Utility function to call go-whisk framework to make action
func (deployer *ServiceDeployer) createAction(pkgname string, action *whisk.Action) error {
	// call ActionService Thru Client
	if deployer.DeployActionInPackage {
		// the action will be created under package with pattern 'packagename/actionname'
		action.Name = strings.Join([]string{pkgname, action.Name}, "/")
	}
	log.Print("Deploying action " + action.Name + " ... ")
	_, _, err := deployer.Client.Actions.Insert(action, true)
	if err != nil {
		wskErr := err.(*whisk.WskError)
		log.Printf("Got error creating action with error message: %v and error code: %v.\n", wskErr.Error(), wskErr.ExitCode)
		return err
	}
	log.Println("Done!")
	return nil
}

func (deployer *ServiceDeployer) UnDeploy(verifiedPlan *DeploymentApplication) error {
	if deployer.IsInteractive == true {
		deployer.printDeploymentAssets(verifiedPlan)
		reader := bufio.NewReader(os.Stdin)

		fmt.Print("Do you really want to undeploy this? (y/N): ")

		text, _ := reader.ReadString('\n')
		text = strings.TrimSpace(text)

		if text == "" {
			text = "n"
		}

		if strings.EqualFold(text, "y") || strings.EqualFold(text, "yes") {
			deployer.InteractiveChoice = true

			if err := deployer.unDeployAssets(verifiedPlan); err != nil {
				fmt.Println("\nUndeployment did not complete sucessfully.")
				return err
			}

			fmt.Println("\nDeployment removed successfully.")
			return nil

		} else {
			deployer.InteractiveChoice = false
			fmt.Println("OK. Cancelling undeployment")
			return nil
		}
	}

	// non-interactive
	if err := deployer.unDeployAssets(verifiedPlan); err != nil {
		fmt.Println("\nUndeployment did not complete sucessfully.")
		return err
	}

	fmt.Println("\nDeployment removed successfully.")
	return nil

}

func (deployer *ServiceDeployer) unDeployAssets(verifiedPlan *DeploymentApplication) error {

	if err := deployer.UnDeployActions(verifiedPlan); err != nil {
		return err
	}

	if err := deployer.UnDeploySequences(verifiedPlan); err != nil {
		return err
	}

	if err := deployer.UnDeployTriggers(verifiedPlan); err != nil {
		return err
	}

	if err := deployer.UnDeployRules(verifiedPlan); err != nil {
		return err
	}

	if err := deployer.UnDeployPackages(verifiedPlan); err != nil {
		return err
	}

	return nil

}

func (deployer *ServiceDeployer) UnDeployPackages(deployment *DeploymentApplication) error {
	for _, pack := range deployment.Packages {
		deployer.deletePackage(pack.Package)
	}
	return nil
}

func (deployer *ServiceDeployer) UnDeploySequences(deployment *DeploymentApplication) error {

	for _, pack := range deployment.Packages {
		for _, action := range pack.Sequences {
			deployer.deleteAction(pack.Package.Name, action.Action)
		}
	}
	return nil
}

// DeployActions into OpenWhisk
func (deployer *ServiceDeployer) UnDeployActions(deployment *DeploymentApplication) error {

	for _, pack := range deployment.Packages {
		for _, action := range pack.Actions {
			err := deployer.deleteAction(pack.Package.Name, action.Action)
			if err != nil {
				return err
			}
		}
	}
	return nil
}

// Deploy Triggers into OpenWhisk
func (deployer *ServiceDeployer) UnDeployTriggers(deployment *DeploymentApplication) error {

	for _, trigger := range deployment.Triggers {
		if feedname, isFeed := utils.IsFeedAction(trigger); isFeed {
			deployer.deleteFeedAction(trigger, feedname)
		} else {
			deployer.deleteTrigger(trigger)
		}
	}

	return nil

}

// Deploy Rules into OpenWhisk
func (deployer *ServiceDeployer) UnDeployRules(deployment *DeploymentApplication) error {

	for _, rule := range deployment.Rules {
		deployer.deleteRule(rule)

	}
	return nil
}

func (deployer *ServiceDeployer) deletePackage(packa *whisk.Package) {
	fmt.Print("Removing package " + packa.Name + " ... ")
	_, err := deployer.Client.Packages.Delete(packa.Name)
	if err != nil {
		wskErr := err.(*whisk.WskError)
		log.Printf("Got error deleteing package with error message: %v and error code: %v.\n", wskErr.Error(), wskErr.ExitCode)
	}
	fmt.Println("Done!")
}

func (deployer *ServiceDeployer) deleteTrigger(trigger *whisk.Trigger) {
	fmt.Print("Removing trigger " + trigger.Name + " ... ")
	_, _, err := deployer.Client.Triggers.Delete(trigger.Name)
	if err != nil {
		wskErr := err.(*whisk.WskError)
		log.Printf("Got error deleting trigger with error message: %v and error code: %v.\n", wskErr.Error(), wskErr.ExitCode)
	}
	fmt.Println("Done!")
}

func (deployer *ServiceDeployer) deleteFeedAction(trigger *whisk.Trigger, feedName string) {

	params := make(whisk.KeyValueArr, 0)
	params = append(params, whisk.KeyValue{Key: "authKey", Value: deployer.ClientConfig.AuthToken})
	params = append(params, whisk.KeyValue{Key: "lifecycleEvent", Value: "DELETE"})
	params = append(params, whisk.KeyValue{Key: "triggerName", Value: "/" + deployer.Client.Namespace + "/" + trigger.Name})

	trigger.Parameters = nil

	_, _, err := deployer.Client.Triggers.Delete(trigger.Name)
	if err != nil {
		wskErr := err.(*whisk.WskError)
		log.Printf("Got error deleting trigger with error message: %v and error code: %v.\n", wskErr.Error(), wskErr.ExitCode)
	} else {
		parameters := make(map[string]interface{})
		for _, keyVal := range params {
			parameters[keyVal.Key] = keyVal.Value
		}

		qName, err := utils.ParseQualifiedName(feedName, deployer.ClientConfig.Namespace)

		utils.Check(err)

		namespace := deployer.Client.Namespace
		deployer.Client.Namespace = qName.Namespace
		_, _, err = deployer.Client.Actions.Invoke(qName.EntityName, parameters, true, true)
		deployer.Client.Namespace = namespace

		if err != nil {
			wskErr := err.(*whisk.WskError)
			log.Printf("Got error deleting trigger feed with error message: %v and error code: %v.\n", wskErr.Error(), wskErr.ExitCode)
		}
	}
	fmt.Println("Done!")
}

func (deployer *ServiceDeployer) deleteRule(rule *whisk.Rule) {
	fmt.Print("Removing rule " + rule.Name + " ... ")
	_, _, err := deployer.Client.Rules.SetState(rule.Name, "inactive")

	if err != nil {
		wskErr := err.(*whisk.WskError)
		log.Printf("Got error deleting rule with error message: %v and error code: %v.\n", wskErr.Error(), wskErr.ExitCode)
	} else {

		_, err = deployer.Client.Rules.Delete(rule.Name)

		if err != nil {
			wskErr := err.(*whisk.WskError)
			log.Printf("Got error deleting rule with error message: %v and error code: %v.\n", wskErr.Error(), wskErr.ExitCode)
		}

		fmt.Println("Done!")
	}
}

// Utility function to call go-whisk framework to make action
func (deployer *ServiceDeployer) deleteAction(pkgname string, action *whisk.Action) error {
	// call ActionService Thru Client
	if deployer.DeployActionInPackage {
		// the action will be deleted under package with pattern 'packagename/actionname'
		action.Name = strings.Join([]string{pkgname, action.Name}, "/")
	}

	fmt.Print("Removing action " + action.Name + " ... ")
	_, err := deployer.Client.Actions.Delete(action.Name)
	if err != nil {
		wskErr := err.(*whisk.WskError)
		log.Printf("Got error deleting action with error message: %v and error code: %v.\n", wskErr.Error(), wskErr.ExitCode)
		return err
	}
	fmt.Println("Done!")
	return nil
}

// from whisk go client
func (deployer *ServiceDeployer) getQualifiedName(name string, namespace string) string {
	if strings.HasPrefix(name, "/") {
		return name
	} else if strings.HasPrefix(namespace, "/") {
		return fmt.Sprintf("%s/%s", namespace, name)
	} else {
		if len(namespace) == 0 {
			namespace = deployer.ClientConfig.Namespace
		}
		return fmt.Sprintf("/%s/%s", namespace, name)
	}
}

func (deployer *ServiceDeployer) printDeploymentAssets(assets *DeploymentApplication) {

	// pretty ASCII OpenWhisk graphic
	fmt.Println("         ____      ___                   _    _ _     _     _\n        /\\   \\    / _ \\ _ __   ___ _ __ | |  | | |__ (_)___| | __\n   /\\  /__\\   \\  | | | | '_ \\ / _ \\ '_ \\| |  | | '_ \\| / __| |/ /\n  /  \\____ \\  /  | |_| | |_) |  __/ | | | |/\\| | | | | \\__ \\   <\n  \\   \\  /  \\/    \\___/| .__/ \\___|_| |_|__/\\__|_| |_|_|___/_|\\_\\ \n   \\___\\/              |_|\n")

	fmt.Println("Packages:")
	for _, pack := range assets.Packages {
		fmt.Println("Name: " + pack.Package.Name)
		fmt.Println("    bindings: ")
		for _, p := range pack.Package.Parameters {
			value := "?"
			if str, ok := p.Value.(string); ok {
				value = str
			}
			fmt.Println("        - name: " + p.Key + " value: " + value)
		}

		for _, action := range pack.Actions {
			fmt.Println("  * action: " + action.Action.Name)
			fmt.Println("    bindings: ")
			for _, p := range action.Action.Parameters {

				value := "?"
				if str, ok := p.Value.(string); ok {
					value = str
				}
				fmt.Println("        - name: " + p.Key + " value: " + value)
			}
			fmt.Println("    annotations: ")
			for _, p := range action.Action.Annotations {
				fmt.Printf("        - %s : %v\n", p.Key, p.Value)

			}
		}

		fmt.Println("")
		for _, action := range pack.Sequences {
			fmt.Println("  * sequence: " + action.Action.Name)
		}

		fmt.Println("")
	}

	fmt.Println("Triggers:")
	for _, trigger := range assets.Triggers {
		fmt.Println("* trigger: " + trigger.Name)
		fmt.Println("    bindings: ")

		for _, p := range trigger.Parameters {

			value := "?"
			if str, ok := p.Value.(string); ok {
				value = str
			}
			fmt.Println("        - name: " + p.Key + " value: " + value)
		}

		fmt.Println("    annotations: ")
		for _, p := range trigger.Annotations {

			value := "?"
			if str, ok := p.Value.(string); ok {
				value = str
			}
			fmt.Println("        - name: " + p.Key + " value: " + value)
		}
	}

	fmt.Println("\n Rules")
	for _, rule := range assets.Rules {
		fmt.Println("* rule: " + rule.Name)
		fmt.Println("    - trigger: " + rule.Trigger.(string) + "\n    - action: " + rule.Action.(string))
	}

	fmt.Println("")

}
