/*
 * 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 (
	"github.com/apache/incubator-openwhisk-client-go/whisk"
	"github.com/apache/incubator-openwhisk-wskdeploy/utils"
)

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

type ParseYaml interface {
	Unmarshal(input []byte, deploy *YAML) error
	Marshal(manifest *YAML) (output []byte, err error)

	//Compose Package entity according to yaml content
	ComposePackages(manifestpath string) ([]*whisk.Package, error)

	// Compose Action entities according to yaml content
	ComposeActions(manifestpath string) ([]*whisk.Action, error)

	// Compose Trigger entities according to deployment and manifest yaml content
	ComposeTriggers(manifestpath string, deploymentpath string) ([]*whisk.Trigger, error)

	// Compose Rule entities according to yaml content
	ComposeRules(manifestpath string) ([]*whisk.Rule, error)
}

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

type Action struct {
	//mapping to wsk.Action.Version
	Version  string `yaml:"version"`           //used in manifest.yaml
	Location string `yaml:"location"`          //deprecated, used in manifest.yaml
	Function string `yaml:"function"`          //used in manifest.yaml
	Runtime  string `yaml:"runtime,omitempty"` //used in manifest.yaml
	//mapping to wsk.Action.Namespace
	Namespace  string               `yaml:"namespace"`  //used in deployment.yaml
	Credential string               `yaml:"credential"` //used in deployment.yaml
	Inputs     map[string]Parameter `yaml:"inputs"`     //used in both manifest.yaml and deployment.yaml
	Outputs    map[string]Parameter `yaml:"outputs"`    //used in manifest.yaml
	//mapping to wsk.Action.Name
	Name        string
	Annotations map[string]interface{} `yaml:"annotations,omitempty"`
	//Parameters  map[string]interface{} `yaml:parameters` // used in manifest.yaml
	ExposedUrl string  `yaml:"exposedUrl"` // used in manifest.yaml
	Webexport  string  `yaml:"web-export"` // used in manifest.yaml
	Main       string  `yaml:"main"`       // used in manifest.yaml
	Limits     *Limits `yaml:"limits"`     // used in manifest.yaml
}

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"` //used in manifest.yaml
	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"` // JSON Value
	Required    bool        `yaml:"required,omitempty"`
	Default     interface{} `yaml:"default,omitempty"`
	Status      string      `yaml:"status,omitempty"`
	Schema      interface{} `yaml:"schema,omitempty"`
	multiline   bool
}

type Trigger struct {
	//mapping to ????
	Feed string `yaml:"feed"` //used in manifest.yaml
	//mapping to wsk.Trigger.Namespace
	Namespace  string               `yaml:"namespace"`  //used in deployment.yaml
	Credential string               `yaml:"credential"` //used in deployment.yaml
	Inputs     map[string]Parameter `yaml:"inputs"`     //used in deployment.yaml
	//mapping to wsk.Trigger.Name
	Name        string
	Annotations map[string]interface{} `yaml:"annotations,omitempty"`
	Source      string                 `yaml:source` // deprecated, used in manifest.yaml
	//Parameters  map[string]interface{} `yaml:parameters` // used in manifest.yaml
}

type Feed struct {
	Namespace  string            `yaml:"namespace"`  //used in deployment.yaml
	Credential string            `yaml:"credential"` //used in both manifest.yaml and deployment.yaml
	Inputs     map[string]string `yaml:"inputs"`     //used in deployment.yaml
	Location   string            `yaml:"location"`   //used in manifest.yaml
	Action     string            `yaml:"action"`     //used in manifest.yaml
	//TODO: need to define operation structure
	Operations map[string]interface{} `yaml:"operations"` //used in manifest.yaml
	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
}

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

type Package struct {
	//mapping to wsk.SentPackageNoPublish.Name
	Packagename string `yaml:"name"` //used in manifest.yaml
	//mapping to wsk.SentPackageNoPublish.Version
	Version      string                `yaml:"version"` //used in manifest.yaml, mandatory
	License      string                `yaml:"license"` //used in manifest.yaml, mandatory
	Repositories []Repository          `yaml:"repositories,omitempty"`
	Dependencies map[string]Dependency `yaml: dependencies` //used in manifest.yaml
	//mapping to wsk.SentPackageNoPublish.Namespace
	Namespace   string                 `yaml:"namespace"`  //used in both manifest.yaml and deployment.yaml
	Credential  string                 `yaml:"credential"` //used in both manifest.yaml and deployment.yaml
	ApiHost     string                 `yaml:"apiHost"`    //used in both manifest.yaml and deployment.yaml
	Actions     map[string]Action      `yaml:"actions"`    //used in both manifest.yaml and deployment.yaml
	Triggers    map[string]Trigger     `yaml:"triggers"`   //used in both manifest.yaml and deployment.yaml
	Feeds       map[string]Feed        `yaml:"feeds"`      //used in both manifest.yaml and deployment.yaml
	Rules       map[string]Rule        `yaml:"rules"`      //used in both manifest.yaml and deployment.yaml
	Inputs      map[string]Parameter   `yaml:"inputs"`     //deprecated, used in deployment.yaml
	Sequences   map[string]Sequence    `yaml:"sequences"`
	Annotations map[string]interface{} `yaml:"annotations,omitempty"`
	//Parameters  map[string]interface{} `yaml: parameters` // used in manifest.yaml
	Apis map[string]map[string]map[string]map[string]string `yaml:"apis"` //used in manifest.yaml
}

type Project struct {
	Name       string             `yaml:"name"`      //used in deployment.yaml
	Namespace  string             `yaml:"namespace"` //used in deployment.yaml
	Credential string             `yaml:"credential"`
	ApiHost    string             `yaml:"apiHost"`
	Version    string             `yaml:"version"`
	Packages   map[string]Package `yaml:"packages"` //used in deployment.yaml
	Package    Package            `yaml:"package"`  // being deprecated, used in deployment.yaml
}

type YAML struct {
	Application Project            `yaml:"application"` //used in deployment.yaml (being deprecated)
	Project     Project            `yaml:"project"`     //used in deployment.yaml
	Packages    map[string]Package `yaml:"packages"`    //used in deployment.yaml
	Package     Package            `yaml:"package"`
	Filepath    string             //file path of the yaml file
}

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

func convertSinglePackageName(packageName string) string {
	if len(packageName) != 0 {
		packageNameEnv := utils.GetEnvVar(packageName)
		if str, ok := packageNameEnv.(string); ok {
			return str
		} else {
			return packageName
		}
	}
	return packageName
}

func convertPackageName(packageMap map[string]Package) map[string]Package {
	packages := make(map[string]Package)
	for packName, depPacks := range packageMap {
		name := packName
		packageName := utils.GetEnvVar(packName)
		if str, ok := packageName.(string); ok {
			name = str
		}
		depPacks.Packagename = convertSinglePackageName(depPacks.Packagename)
		packages[name] = depPacks
	}
	return packages
}

func ReadEnvVariable(yaml *YAML) *YAML {
	if yaml.Application.Name != "" {
		yaml.Application.Package.Packagename = convertSinglePackageName(yaml.Application.Package.Packagename)
		yaml.Package.Packagename = convertSinglePackageName(yaml.Package.Packagename)
		yaml.Application.Packages = convertPackageName(yaml.Application.Packages)
	} else {
		yaml.Project.Package.Packagename = convertSinglePackageName(yaml.Project.Package.Packagename)
		yaml.Package.Packagename = convertSinglePackageName(yaml.Package.Packagename)
		yaml.Project.Packages = convertPackageName(yaml.Project.Packages)
	}
	yaml.Packages = convertPackageName(yaml.Packages)
	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 = rule.Name
	//wskrule.Namespace = rule.Namespace
	pub := false
	wskrule.Publish = &pub
	wskrule.Trigger = rule.Trigger

	wskrule.Action = 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
					api.Action = action
					apis = append(apis, api)
				}
			}
		}
	}
	return apis
}
