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

import (
	"strings"

	"github.com/apache/incubator-openwhisk-client-go/whisk"
	"github.com/apache/incubator-openwhisk-wskdeploy/utils"
	"github.com/apache/incubator-openwhisk-wskdeploy/wskenv"
)

// YAML schema key names
// DO NOT translate
const (
	YAML_KEY_ACTION     = "action"
	YAML_KEY_ANNOTATION = "annotation"
	YAML_KEY_API        = "api"
	YAML_KEY_FEED       = "feed"
	YAML_KEY_MANIFEST   = "manifest"
	YAML_KEY_NAMESPACE  = "namespace"
	YAML_KEY_PACKAGE    = "package"
	YAML_KEY_PACKAGES   = "packages"
	YAML_KEY_PROJECT    = "project"
	YAML_KEY_RULE       = "rule"
	YAML_KEY_SEQUENCE   = "sequence"
	YAML_KEY_TRIGGER    = "trigger"
	YAML_KEY_SOURCE     = "source"
	YAML_KEY_BLACKBOX   = "blackbox"
)

// YAML schema key values
const (
	YAML_VALUE_BRANCH_MASTER = "master"
)

// default values
const (
	DEFAULT_PACKAGE_LICENSE = "unlicensed"
	DEFAULT_PACKAGE_VERSION = "0.0.1"
)

// Known Limit values
const (
	// supported
	LIMIT_VALUE_TIMEOUT     = "timeout"
	LIMIT_VALUE_MEMORY_SIZE = "memorySize"
	LIMIT_VALUE_LOG_SIZE    = "logSize"
	// unsupported
	LIMIT_VALUE_CONCURRENT_ACTIVATIONS = "concurrentActivations"
	LIMIT_VALUE_USER_INVOCATION_RATE   = "userInvocationRate"
	LIMIT_VALUE_CODE_SIZE              = "codeSize"
	LIMIT_VALUE_PARAMETER_SIZE         = "parameterSize"
)

var LIMITS_SUPPORTED = [](string){
	LIMIT_VALUE_TIMEOUT,
	LIMIT_VALUE_MEMORY_SIZE,
	LIMIT_VALUE_LOG_SIZE,
}

var LIMITS_UNSUPPORTED = [](string){
	LIMIT_VALUE_CONCURRENT_ACTIVATIONS,
	LIMIT_VALUE_USER_INVOCATION_RATE,
	LIMIT_VALUE_CODE_SIZE,
	LIMIT_VALUE_PARAMETER_SIZE,
}

// structs that denote the sample manifest.yaml, wrapped yaml.v2
func NewYAMLParser() *YAMLParser {
	return &YAMLParser{}
}

type YAMLParser struct {
	manifests []*YAML
	lastID    uint32
}

// Action is mapped to wsk.Action.*
// Used in both manifest and deployment files
type Action struct {
	Name string
	// TODO(): deprecate location in favor of function
	Location    string                 `yaml:"location"`
	Version     string                 `yaml:"version"`
	Function    string                 `yaml:"function"`
	Code        string                 `yaml:"code"`
	Runtime     string                 `yaml:"runtime,omitempty"`
	Namespace   string                 `yaml:"namespace"`
	Credential  string                 `yaml:"credential"`
	ExposedUrl  string                 `yaml:"exposedUrl"`
	Webexport   string                 `yaml:"web-export"`
	Web         string                 `yaml:"web"`
	Main        string                 `yaml:"main"`
	Docker      string                 `yaml:"docker,omitempty"`
	Native      bool                   `yaml:"native,omitempty"`
	Conductor   bool                   `yaml:"conductor,omitempty"`
	Limits      *Limits                `yaml:"limits"`
	Inputs      map[string]Parameter   `yaml:"inputs"`
	Outputs     map[string]Parameter   `yaml:"outputs"`
	Annotations map[string]interface{} `yaml:"annotations,omitempty"`
	// TODO() this is propoagated from package to every action within that package
	//Parameters  map[string]interface{} `yaml:parameters`
}

type Limits struct {
	Timeout               *int `yaml:"timeout,omitempty"`               //in ms, [100 ms,300000ms]
	Memory                *int `yaml:"memorySize,omitempty"`            //in MB, [128 MB,512 MB]
	Logsize               *int `yaml:"logSize,omitempty"`               //in MB, [0MB,10MB]
	ConcurrentActivations *int `yaml:"concurrentActivations,omitempty"` //not changeable via APIs
	UserInvocationRate    *int `yaml:"userInvocationRate,omitempty"`    //not changeable via APIs
	CodeSize              *int `yaml:"codeSize,omitempty"`              //not changeable via APIs
	ParameterSize         *int `yaml:"parameterSize,omitempty"`         //not changeable via APIs
}

type Sequence struct {
	Actions     string                 `yaml:"actions"`
	Web         string                 `yaml:"web"`
	Annotations map[string]interface{} `yaml:"annotations,omitempty"`
}

type Dependency struct {
	Version     string                 `yaml:"version,omitempty"`
	Location    string                 `yaml:"location,omitempty"`
	Inputs      map[string]Parameter   `yaml:"inputs"`
	Annotations map[string]interface{} `yaml:"annotations"`
}

type Parameter struct {
	Type        string      `yaml:"type,omitempty"`
	Description string      `yaml:"description,omitempty"`
	Value       interface{} `yaml:"value,omitempty"`
	Required    bool        `yaml:"required,omitempty"`
	Default     interface{} `yaml:"default,omitempty"`
	Status      string      `yaml:"status,omitempty"`
	Schema      interface{} `yaml:"schema,omitempty"`
	multiline   bool
}

// Trigger is mapped wsk.Trigger.*
type Trigger struct {
	Feed        string               `yaml:"feed"`
	Namespace   string               `yaml:"namespace"`
	Credential  string               `yaml:"credential"`
	Inputs      map[string]Parameter `yaml:"inputs"`
	Name        string
	Annotations map[string]interface{} `yaml:"annotations,omitempty"`
	// TODO() this is propoagated from package to trigger within that package
	//Parameters  map[string]interface{} `yaml:parameters`
	// TODO(): deprecated, please delete it
	Source string `yaml:"source"`
}

type Feed struct {
	Namespace  string            `yaml:"namespace"`
	Credential string            `yaml:"credential"`
	Inputs     map[string]string `yaml:"inputs"`
	Location   string            `yaml:"location"`
	Action     string            `yaml:"action"`
	// TODO(): need to define operation structure
	Operations map[string]interface{} `yaml:"operations"`
	Name       string
}

type Rule struct {
	//mapping to wsk.Rule.Trigger
	Trigger string `yaml:"trigger"` //used in manifest.yaml
	//mapping to wsk.Rule.Action
	Action string `yaml:"action"` //used in manifest.yaml
	Rule   string `yaml:"rule"`   //used in manifest.yaml
	//mapping to wsk.Rule.Name
	Name        string
	Annotations map[string]interface{} `yaml:"annotations,omitempty"`
}

type Repository struct {
	Url         string `yaml:"url"`
	Description string `yaml:"description,omitempty"`
	Credential  string `yaml:"credential,omitempty"`
}

type APIMethodResponse struct {
	Method   string `yaml:"method"`
	Response string `yaml:"response"`
}

type Package struct {
	Packagename      string                                                        `yaml:"name"`
	Version          string                                                        `yaml:"version"` //mandatory
	License          string                                                        `yaml:"license"` //mandatory
	Public           bool                                                          `yaml:"public,omitempty"`
	Repositories     []Repository                                                  `yaml:"repositories,omitempty"`
	Dependencies     map[string]Dependency                                         `yaml:"dependencies"`
	Namespace        string                                                        `yaml:"namespace"`
	Credential       string                                                        `yaml:"credential"`
	ApiHost          string                                                        `yaml:"apiHost"`
	ApigwAccessToken string                                                        `yaml:"apigwAccessToken"`
	Actions          map[string]Action                                             `yaml:"actions"`
	Triggers         map[string]Trigger                                            `yaml:"triggers"`
	Feeds            map[string]Feed                                               `yaml:"feeds"`
	Rules            map[string]Rule                                               `yaml:"rules"`
	Inputs           map[string]Parameter                                          `yaml:"inputs"`
	Sequences        map[string]Sequence                                           `yaml:"sequences"`
	Annotations      map[string]interface{}                                        `yaml:"annotations,omitempty"`
	Apis             map[string]map[string]map[string]map[string]APIMethodResponse `yaml:"apis"`
}

type Project struct {
	Name             string               `yaml:"name"`
	Namespace        string               `yaml:"namespace"`
	Credential       string               `yaml:"credential"`
	ApiHost          string               `yaml:"apiHost"`
	ApigwAccessToken string               `yaml:"apigwAccessToken"`
	Version          string               `yaml:"version"`
	Packages         map[string]Package   `yaml:"packages"`
	Inputs           map[string]Parameter `yaml: parameters`
}

type YAML struct {
	Project  Project            `yaml:"project"`
	Packages map[string]Package `yaml:"packages"`
	Filepath string             //file path of the yaml file
}

type DisplayInputs struct {
	Name   string
	Inputs map[string]interface{}
}

type PackageInputs struct {
	PackageName string
	Inputs      map[string]Parameter
}

// function to return web-export or web depending on what is specified
// in manifest and deployment files
func (action *Action) GetWeb() string {
	if len(action.Web) == 0 && len(action.Webexport) != 0 {
		return action.Webexport
	}
	return action.Web
}

// function to return Project or Application depending on what is specified in
// manifest and deployment files
func (yaml *YAML) GetProject() Project {
	return yaml.Project
}

func convertPackageName(packageMap map[string]Package, inputs map[string]Parameter) map[string]Package {
	packages := make(map[string]Package)
	for packName, depPacks := range packageMap {
		name := packName
		packageName := wskenv.InterpolateStringWithEnvVar(packName)
		if str, ok := packageName.(string); ok {
			name = str
		}
		if inputs != nil {
			if len(name) == 0 {
				packName = wskenv.GetEnvVarName(packName)
				name = wskenv.ConvertSingleName(inputs[packName].Value.(string))
			}
		}
		depPacks.Packagename = wskenv.ConvertSingleName(depPacks.Packagename)
		packages[name] = depPacks
	}
	return packages
}

func ReadEnvVariable(yaml *YAML) *YAML {
	yaml.Project.Packages = convertPackageName(yaml.Project.Packages, yaml.Project.Inputs)
	yaml.Packages = convertPackageName(yaml.Packages, nil)
	return yaml
}

//********************Trigger functions*************************//
//add the key/value array as the annotations of the trigger.
func (trigger *Trigger) ComposeWskTrigger(kvarr []whisk.KeyValue) *whisk.Trigger {
	wsktrigger := new(whisk.Trigger)
	wsktrigger.Name = trigger.Name
	wsktrigger.Namespace = trigger.Namespace
	pub := false
	wsktrigger.Publish = &pub
	wsktrigger.Annotations = kvarr
	return wsktrigger
}

//********************Rule functions*************************//
func (rule *Rule) ComposeWskRule() *whisk.Rule {
	wskrule := new(whisk.Rule)
	wskrule.Name = wskenv.ConvertSingleName(rule.Name)
	//wskrule.Namespace = rule.Namespace // TODO() ?
	pub := false
	wskrule.Publish = &pub
	wskrule.Trigger = wskenv.ConvertSingleName(rule.Trigger)
	wskrule.Action = wskenv.ConvertSingleName(rule.Action)
	return wskrule
}

//********************Package functions*************************//
func (pkg *Package) ComposeWskPackage() *whisk.Package {
	wskpag := new(whisk.Package)
	wskpag.Name = pkg.Packagename
	wskpag.Namespace = pkg.Namespace
	pub := false
	wskpag.Publish = &pub
	wskpag.Version = pkg.Version
	return wskpag
}

func (pkg *Package) GetActionList() []Action {
	var s1 []Action = make([]Action, 0)
	for action_name, action := range pkg.Actions {
		action.Name = action_name
		s1 = append(s1, action)
	}
	return s1
}

func (pkg *Package) GetTriggerList() []Trigger {
	var s1 []Trigger = make([]Trigger, 0)
	for trigger_name, trigger := range pkg.Triggers {
		trigger.Name = trigger_name
		s1 = append(s1, trigger)
	}
	return s1
}

func (pkg *Package) GetRuleList() []Rule {
	var s1 []Rule = make([]Rule, 0)
	for rule_name, rule := range pkg.Rules {
		rule.Name = rule_name
		s1 = append(s1, rule)
	}
	return s1
}

//This is for parse the deployment yaml file.
func (pkg *Package) GetFeedList() []Feed {
	var s1 []Feed = make([]Feed, 0)
	for feed_name, feed := range pkg.Feeds {
		feed.Name = feed_name
		s1 = append(s1, feed)
	}
	return s1
}

// This is for parse the manifest yaml file.
func (pkg *Package) GetApis() []*whisk.Api {
	var apis = make([]*whisk.Api, 0)
	for k, v := range pkg.Apis {
		var apiName string = k
		for k, v := range v {
			var gatewayBasePath string = k
			for k, v := range v {
				var gatewayRelPath string = k
				for k, v := range v {
					api := &whisk.Api{}
					api.ApiName = apiName
					api.GatewayBasePath = gatewayBasePath
					api.GatewayRelPath = gatewayRelPath
					action := &whisk.ApiAction{}
					action.Name = k
					action.BackendMethod = v.Method
					api.Action = action
					apis = append(apis, api)
				}
			}
		}
	}
	return apis
}

//********************YAML functions*************************//
func filterAnnotations(annotations whisk.KeyValueArr) map[string]interface{} {
	res := make(map[string]interface{})
	for _, a := range annotations {
		if a.Key != utils.MANAGED {
			res[a.Key] = a.Value
		}
	}

	return res
}

func (yaml *YAML) ComposeParsersPackage(wskpag whisk.Package) *Package {
	pkg := new(Package)
	pkg.Packagename = wskpag.Name
	pkg.Namespace = wskpag.Namespace
	pkg.Version = wskpag.Version

	for _, keyval := range wskpag.Parameters {
		param := new(Parameter)
		param.Value = keyval.Value
		pkg.Inputs[keyval.Key] = *param
	}

	pkg.Annotations = filterAnnotations(wskpag.Annotations)
	return pkg
}

func (yaml *YAML) ComposeParsersAction(wskact whisk.Action) *Action {
	action := new(Action)
	action.Name = wskact.Name
	action.Namespace = wskact.Namespace
	action.Version = wskact.Version
	action.Main = wskact.Exec.Main

	action.Inputs = make(map[string]Parameter)
	for _, keyval := range wskact.Parameters {
		param := new(Parameter)
		param.Value = keyval.Value
		action.Inputs[keyval.Key] = *param
	}

	action.Annotations = filterAnnotations(wskact.Annotations)

	runtime := strings.Split(wskact.Exec.Kind, ":")[0]
	if strings.ToLower(runtime) == YAML_KEY_BLACKBOX {
		// storing blackbox image reference without saving the code as its impossible
		action.Docker = wskact.Exec.Image
	} else {
		action.Runtime = wskact.Exec.Kind
	}

	return action
}

func (yaml *YAML) ComposeParsersTrigger(wsktrg whisk.Trigger) *Trigger {
	trigger := new(Trigger)
	trigger.Name = wsktrg.Name
	trigger.Namespace = wsktrg.Namespace
	trigger.Inputs = make(map[string]Parameter)
	for _, keyval := range wsktrg.Parameters {
		param := new(Parameter)
		param.Value = keyval.Value
		trigger.Inputs[keyval.Key] = *param
	}

	if feedname, isFeed := utils.IsFeedAction(&wsktrg); isFeed {
		trigger.Source = feedname
	}
	trigger.Annotations = filterAnnotations(wsktrg.Annotations)
	return trigger
}

func (yaml *YAML) ComposeParsersDependency(binding whisk.Binding, bPkg whisk.Package) *Dependency {
	dependency := new(Dependency)
	dependency.Location = "/" + binding.Namespace + "/" + binding.Name

	dependency.Inputs = make(map[string]Parameter)
	for _, keyval := range bPkg.Parameters {
		param := new(Parameter)
		param.Value = keyval.Value
		dependency.Inputs[keyval.Key] = *param
	}
	return dependency
}

func (yaml *YAML) ComposeParsersRule(wskrule whisk.Rule) *Rule {
	rule := new(Rule)
	rule.Name = wskrule.Name

	pa := wskrule.Action.(map[string]interface{})["path"].(string)
	pa = strings.SplitN(pa, "/", 2)[1]

	rule.Action = pa + "/" + wskrule.Action.(map[string]interface{})["name"].(string)
	rule.Trigger = wskrule.Trigger.(map[string]interface{})["name"].(string)

	rule.Annotations = filterAnnotations(wskrule.Annotations)
	return rule
}
