/*
 * 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"`
	Include     [][]string             `yaml:"include,omitempty"`
	Exclude     []string               `yaml:"exclude,omitempty"`
}

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
}
