/*
 * Copyright 2018-present Open Networking Foundation

 * Licensed 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 model

import (
	"fmt"
	"github.com/golang/protobuf/proto"
	"github.com/opencord/voltha-go/common/log"
	"reflect"
	"strings"
)

const (
	NONE string = "none"
)

type Node struct {
	root      *Root
	Type      interface{}
	Branches  map[string]*Branch
	Tags      map[string]Revision
	Proxy     *Proxy
	EventBus  *EventBus
	AutoPrune bool
}

func NewNode(root *Root, initialData interface{}, autoPrune bool, txid string) *Node {
	n := &Node{}

	n.root = root
	n.Branches = make(map[string]*Branch)
	n.Tags = make(map[string]Revision)
	n.Proxy = nil
	n.EventBus = nil
	n.AutoPrune = autoPrune

	if IsProtoMessage(initialData) {
		n.Type = reflect.ValueOf(initialData).Interface()
		dataCopy := proto.Clone(initialData.(proto.Message))
		n.initialize(dataCopy, txid)
	} else if reflect.ValueOf(initialData).IsValid() {
		n.Type = reflect.ValueOf(initialData).Interface()
	} else {
		// not implemented error
		fmt.Errorf("cannot process initial data - %+v", initialData)
	}

	return n
}

func (n *Node) MakeNode(data interface{}, txid string) *Node {
	return NewNode(n.root, data, true, txid)
}

func (n *Node) MakeRevision(branch *Branch, data interface{}, children map[string][]Revision) Revision {
	return n.root.MakeRevision(branch, data, children)
}

func (n *Node) MakeLatest(branch *Branch, revision Revision, changeAnnouncement map[CallbackType][]interface{}) {
	if _, ok := branch.Revisions[revision.GetHash()]; !ok {
		branch.Revisions[revision.GetHash()] = revision
	}

	if branch.Latest == nil || revision.GetHash() != branch.Latest.GetHash() {
		branch.Latest = revision
	}

	if changeAnnouncement != nil && branch.Txid == "" {
		if n.Proxy != nil {
			for changeType, data := range changeAnnouncement {
				// TODO: Invoke callback
				fmt.Printf("invoking callback - changeType: %+v, data:%+v\n", changeType, data)
			}
		}

		for changeType, data := range changeAnnouncement {
			// TODO: send notifications
			fmt.Printf("sending notification - changeType: %+v, data:%+v\n", changeType, data)
		}
	}
}

func (n *Node) Latest() Revision {
	if branch, exists := n.Branches[NONE]; exists {
		return branch.Latest
	}
	return nil
}

func (n *Node) GetHash(hash string) Revision {
	return n.Branches[NONE].Revisions[hash]
}

func (n *Node) initialize(data interface{}, txid string) {
	var children map[string][]Revision
	children = make(map[string][]Revision)
	for fieldName, field := range ChildrenFields(n.Type) {
		_, fieldValue := GetAttributeValue(data, fieldName, 0)

		if fieldValue.IsValid() {
			if field.IsContainer {
				if field.Key != "" {
					var keysSeen []string

					for i := 0; i < fieldValue.Len(); i++ {
						v := fieldValue.Index(i)
						rev := n.MakeNode(v.Interface(), txid).Latest()
						_, key := GetAttributeValue(v.Interface(), field.Key, 0)
						for _, k := range keysSeen {
							if k == key.String() {
								fmt.Errorf("duplicate key - %s", k)
							}
						}
						children[fieldName] = append(children[fieldName], rev)
						keysSeen = append(keysSeen, key.String())
					}

				} else {
					for i := 0; i < fieldValue.Len(); i++ {
						v := fieldValue.Index(i)
						children[fieldName] = append(children[fieldName], n.MakeNode(v.Interface(), txid).Latest())
					}
				}
			} else {
				children[fieldName] = append(children[fieldName], n.MakeNode(fieldValue.Interface(), txid).Latest())
			}
		} else {
			fmt.Errorf("field is invalid - %+v", fieldValue)
		}
	}
	// FIXME: ClearField???  No such method in go protos.  Reset?
	//data.ClearField(field_name)
	branch := NewBranch(n, "", nil, n.AutoPrune)
	rev := n.MakeRevision(branch, data, children)
	n.MakeLatest(branch, rev, nil)

	if txid == "" {
		n.Branches[NONE] = branch
	} else {
		n.Branches[txid] = branch
	}
}

//
// Get operation
//
func (n *Node) Get(path string, hash string, depth int, deep bool, txid string) interface{} {
	if deep {
		depth = -1
	}

	for strings.HasPrefix(path, "/") {
		path = path[1:]
	}

	var branch *Branch
	var rev Revision

	// FIXME: should empty txid be cleaned up?
	if branch = n.Branches[txid]; txid == "" || branch == nil {
		branch = n.Branches[NONE]
	}

	if hash != "" {
		rev = branch.Revisions[hash]
	} else {
		rev = branch.Latest
	}

	return n.get(rev, path, depth)
}

func (n *Node) findRevByKey(revs []Revision, keyName string, value string) (int, Revision) {
	for i, rev := range revs {
		dataValue := reflect.ValueOf(rev.GetData())
		dataStruct := GetAttributeStructure(rev.GetData(), keyName, 0)

		fieldValue := dataValue.Elem().FieldByName(dataStruct.Name)

		if fieldValue.Interface().(string) == value {
			return i, rev
		}
	}

	fmt.Errorf("key %s=%s not found", keyName, value)

	return -1, nil
}

func (n *Node) get(rev Revision, path string, depth int) interface{} {
	if path == "" {
		return n.doGet(rev, depth)
	}

	partition := strings.SplitN(path, "/", 2)
	name := partition[0]

	if len(partition) < 2 {
		path = ""
	} else {
		path = partition[1]
	}

	names := ChildrenFields(n.Type)
	field := names[name]

	if field != nil && field.IsContainer {
		if field.Key != "" {
			children := rev.GetChildren()[name]
			if path != "" {
				partition = strings.SplitN(path, "/", 2)
				key := partition[0]
				path = ""
				key = field.KeyFromStr(key).(string)
				if _, childRev := n.findRevByKey(children, field.Key, key); childRev == nil {
					return nil
				} else {
					childNode := childRev.GetNode()
					return childNode.get(childRev, path, depth)
				}
			} else {
				var response []interface{}
				for _, childRev := range children {
					childNode := childRev.GetNode()
					value := childNode.doGet(childRev, depth)
					response = append(response, value)
				}
				return response
			}
		} else {
			var response []interface{}
			if path != "" {
				// TODO: raise error
				return response
			}
			for _, childRev := range rev.GetChildren()[name] {
				childNode := childRev.GetNode()
				value := childNode.doGet(childRev, depth)
				response = append(response, value)
			}
			return response
		}
	} else {
		c1 := rev.GetChildren()[name]
		childRev := c1[0]
		childNode := childRev.GetNode()
		return childNode.get(childRev, path, depth)
	}
	return nil
}

func (n *Node) doGet(rev Revision, depth int) interface{} {
	msg := rev.Get(depth)

	if n.Proxy != nil {
		// TODO: invoke GET callback
		fmt.Println("invoking proxy GET Callbacks")
	}
	return msg
}

//
// Update operation
//
func (n *Node) Update(path string, data interface{}, strict bool, txid string, makeBranch t_makeBranch) Revision {
	// FIXME: is this required ... a bit overkill to take out a "/"
	for strings.HasPrefix(path, "/") {
		path = path[1:]
	}

	var branch *Branch
	var ok bool
	if txid == "" {
		branch = n.Branches[NONE]
	} else if branch, ok = n.Branches[txid]; !ok {
		branch = makeBranch(n)
	}

	log.Debugf("Branch data : %+v, Passed data: %+v", branch.Latest.GetData(), data)

	if path == "" {
		return n.doUpdate(branch, data, strict)
	}

	// TODO missing some code here...
	rev := branch.Latest

	partition := strings.SplitN(path, "/", 2)
	name := partition[0]

	if len(partition) < 2 {
		path = ""
	} else {
		path = partition[1]
	}

	field := ChildrenFields(n.Type)[name]
	var children []Revision

	if field.IsContainer {
		if path == "" {
			fmt.Errorf("cannot update a list\n")
		} else if field.Key != "" {
			partition := strings.SplitN(path, "/", 2)
			key := partition[0]
			if len(partition) < 2 {
				path = ""
			} else {
				path = partition[1]
			}
			key = field.KeyFromStr(key).(string)
			// TODO. Est-ce que le copy ne fonctionne pas? dois-je plutôt faire un clone de chaque item?
			for _, v := range rev.GetChildren()[name] {
				revCopy := reflect.ValueOf(v).Interface().(Revision)
				children = append(children, revCopy)
			}
			idx, childRev := n.findRevByKey(children, field.Key, key)
			childNode := childRev.GetNode()
			newChildRev := childNode.Update(path, data, strict, txid, makeBranch)
			if newChildRev.GetHash() == childRev.GetHash() {
				if newChildRev != childRev {
					log.Debug("clear-hash - %s %+v", newChildRev.GetHash(), newChildRev)
					newChildRev.ClearHash()
				}
				return branch.Latest
			}
			if _, newKey := GetAttributeValue(newChildRev.GetData(), field.Key, 0); newKey.Interface().(string) != key {
				fmt.Errorf("cannot change key field\n")
			}
			children[idx] = newChildRev
			rev = rev.UpdateChildren(name, children, branch)
			n.root.MakeLatest(branch, rev, nil)
			return rev
		} else {
			fmt.Errorf("cannot index into container with no keys\n")
		}
	} else {
		childRev := rev.GetChildren()[name][0]
		childNode := childRev.GetNode()
		newChildRev := childNode.Update(path, data, strict, txid, makeBranch)
		rev = rev.UpdateChildren(name, []Revision{newChildRev}, branch)
		n.root.MakeLatest(branch, rev, nil)
		return rev
	}
	return nil
}

func (n *Node) doUpdate(branch *Branch, data interface{}, strict bool) Revision {
	log.Debugf("Comparing types - expected: %+v, actual: %+v", reflect.ValueOf(n.Type).Type(), reflect.TypeOf(data))

	if reflect.TypeOf(data) != reflect.ValueOf(n.Type).Type() {
		// TODO raise error
		fmt.Errorf("data does not match type: %+v", n.Type)
		return nil
	}

	// TODO: validate that this actually works
	//if n.hasChildren(data) {
	//	return nil
	//}

	if n.Proxy != nil {
		// TODO: n.proxy.InvokeCallbacks(CallbackType.PRE_UPDATE, data)
		fmt.Println("invoking proxy PRE_UPDATE Callbacks")
	}
	if !reflect.DeepEqual(branch.Latest.GetData(), data) {
		if strict {
			// TODO: checkAccessViolations(data, Branch.GetLatest.data)
			fmt.Println("checking access violations")
		}
		rev := branch.Latest.UpdateData(data, branch)
		n.root.MakeLatest(branch, rev, nil) // TODO -> changeAnnouncement needs to be a tuple (CallbackType.
		// POST_UPDATE, rev.data)
		return rev
	} else {
		return branch.Latest
	}
}

//
// Add operation
//
func (n *Node) Add(path string, data interface{}, txid string, makeBranch t_makeBranch) Revision {
	for strings.HasPrefix(path, "/") {
		path = path[1:]
	}
	if path == "" {
		// TODO raise error
		fmt.Errorf("cannot add for non-container mode\n")
	}

	var branch *Branch
	var ok bool
	if txid == "" {
		branch = n.Branches[NONE]
	} else if branch, ok = n.Branches[txid]; !ok {
		branch = makeBranch(n)
	}

	rev := branch.Latest

	partition := strings.SplitN(path, "/", 2)
	name := partition[0]

	if len(partition) < 2 {
		path = ""
	} else {
		path = partition[1]
	}

	field := ChildrenFields(n.Type)[name]
	var children []Revision

	if field.IsContainer {
		if path == "" {
			if field.Key != "" {
				if n.Proxy != nil {
					// TODO -> n.proxy.InvokeCallbacks(PRE_ADD, data)
					fmt.Println("invoking proxy PRE_ADD Callbacks")
				}

				for _, v := range rev.GetChildren()[name] {
					revCopy := reflect.ValueOf(v).Interface().(Revision)
					children = append(children, revCopy)
				}
				_, key := GetAttributeValue(data, field.Key, 0)
				if _, rev := n.findRevByKey(children, field.Key, key.String()); rev != nil {
					// TODO raise error
					fmt.Errorf("duplicate key found: %s", key.String())
				}

				childRev := n.MakeNode(data, "").Latest()
				children = append(children, childRev)
				rev := rev.UpdateChildren(name, children, branch)
				n.root.MakeLatest(branch, rev, nil) // TODO -> changeAnnouncement needs to be a tuple (CallbackType.
				// POST_ADD, rev.data)
				return rev
			} else {
				fmt.Errorf("cannot add to non-keyed container\n")
			}
		} else if field.Key != "" {
			partition := strings.SplitN(path, "/", 2)
			key := partition[0]
			if len(partition) < 2 {
				path = ""
			} else {
				path = partition[1]
			}
			key = field.KeyFromStr(key).(string)
			copy(children, rev.GetChildren()[name])
			idx, childRev := n.findRevByKey(children, field.Key, key)
			childNode := childRev.GetNode()
			newChildRev := childNode.Add(path, data, txid, makeBranch)
			children[idx] = newChildRev
			rev := rev.UpdateChildren(name, children, branch)
			n.root.MakeLatest(branch, rev, nil)
			return rev
		} else {
			fmt.Errorf("cannot add to non-keyed container\n")
		}
	} else {
		fmt.Errorf("cannot add to non-container field\n")
	}
	return nil
}

//
// Remove operation
//
func (n *Node) Remove(path string, txid string, makeBranch t_makeBranch) Revision {
	for strings.HasPrefix(path, "/") {
		path = path[1:]
	}
	if path == "" {
		// TODO raise error
		fmt.Errorf("cannot remove for non-container mode\n")
	}
	var branch *Branch
	var ok bool
	if txid == "" {
		branch = n.Branches[NONE]
	} else if branch, ok = n.Branches[txid]; !ok {
		branch = makeBranch(n)
	}

	rev := branch.Latest

	partition := strings.SplitN(path, "/", 2)
	name := partition[0]
	if len(partition) < 2 {
		path = ""
	} else {
		path = partition[1]
	}

	field := ChildrenFields(n.Type)[name]
	var children []Revision
	post_anno := make(map[CallbackType][]interface{})

	if field.IsContainer {
		if path == "" {
			fmt.Errorf("cannot remove without a key\n")
		} else if field.Key != "" {
			partition := strings.SplitN(path, "/", 2)
			key := partition[0]
			if len(partition) < 2 {
				path = ""
			} else {
				path = partition[1]
			}
			key = field.KeyFromStr(key).(string)
			if path != "" {
				for _, v := range rev.GetChildren()[name] {
					newV := reflect.ValueOf(v).Interface().(Revision)
					children = append(children, newV)
				}
				idx, childRev := n.findRevByKey(children, field.Key, key)
				childNode := childRev.GetNode()
				newChildRev := childNode.Remove(path, txid, makeBranch)
				children[idx] = newChildRev
				rev := rev.UpdateChildren(name, children, branch)
				n.root.MakeLatest(branch, rev, nil)
				return rev
			} else {
				for _, v := range rev.GetChildren()[name] {
					newV := reflect.ValueOf(v).Interface().(Revision)
					children = append(children, newV)
				}
				idx, childRev := n.findRevByKey(children, field.Key, key)
				if n.Proxy != nil {
					data := childRev.GetData()
					fmt.Println("invoking proxy PRE_REMOVE Callbacks")
					fmt.Printf("setting POST_REMOVE Callbacks : %+v\n", data)
				} else {
					fmt.Println("setting POST_REMOVE Callbacks")
				}
				children = append(children[:idx], children[idx+1:]...)
				rev := rev.UpdateChildren(name, children, branch)
				n.root.MakeLatest(branch, rev, post_anno)
				return rev
			}
		} else {
			fmt.Errorf("cannot add to non-keyed container\n")
		}
	} else {
		fmt.Errorf("cannot add to non-container field\n")
	}

	return nil
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Branching ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

type t_makeBranch func(*Node) *Branch

func (n *Node) makeTxBranch(txid string) *Branch {
	branchPoint := n.Branches[NONE].Latest
	branch := NewBranch(n, txid, branchPoint, true)
	n.Branches[txid] = branch
	return branch
}

func (n *Node) deleteTxBranch(txid string) {
	delete(n.Branches, txid)
}

func (n *Node) mergeChild(txid string, dryRun bool) func(Revision) Revision {
	f := func(rev Revision) Revision {
		childBranch := rev.GetBranch()

		if childBranch.Txid == txid {
			rev = childBranch.Node.mergeTxBranch(txid, dryRun)
		}

		return rev
	}
	return f
}

func (n *Node) mergeTxBranch(txid string, dryRun bool) Revision {
	srcBranch := n.Branches[txid]
	dstBranch := n.Branches[NONE]

	forkRev := srcBranch.Origin
	srcRev := srcBranch.Latest
	dstRev := dstBranch.Latest

	rev, changes := Merge3Way(forkRev, srcRev, dstRev, n.mergeChild(txid, dryRun), dryRun)

	if !dryRun {
		n.root.MakeLatest(dstBranch, rev, changes)
		delete(n.Branches, txid)
	}

	return rev
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Diff utility ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

//func (n *Node) diff(hash1, hash2, txid string) {
//	branch := n.Branches[txid]
//	rev1 := branch.get(hash1)
//	rev2 := branch.get(hash2)
//
//	if rev1.GetHash() == rev2.GetHash() {
//		// empty patch
//	} else {
//		// translate data to json and generate patch
//		patch, err := jsonpatch.MakePatch(rev1.GetData(), rev2.GetData())
//		patch.
//	}
//}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Tag utility ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

// TODO: is tag mgmt used in the python implementation? Need to validate

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Internals ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

func (n *Node) hasChildren(data interface{}) bool {
	for fieldName, field := range ChildrenFields(n.Type) {
		_, fieldValue := GetAttributeValue(data, fieldName, 0)

		if (field.IsContainer && fieldValue.Len() > 0) || !fieldValue.IsNil() {
			log.Error("cannot update external children")
			return true
		}
	}

	return false
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Node Proxy ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

func (n *Node) GetProxy(path string, exclusive bool) *Proxy {
	return n.getProxy(path, n.root, path, exclusive)
}
func (n *Node) getProxy(path string, root *Root, fullPath string, exclusive bool) *Proxy {
	for strings.HasPrefix(path, "/") {
		path = path[1:]
	}
	if path == "" {
		return n.makeProxy(n.root, path, exclusive)
	}

	rev := n.Branches[NONE].Latest
	partition := strings.SplitN(path, "/", 2)
	name := partition[0]
	path = partition[1]

	field := ChildrenFields(n.Type)[name]
	if field.IsContainer {
		if path == "" {
			log.Error("cannot proxy a container field")
		}
		if field.Key != "" {
			partition := strings.SplitN(path, "/", 2)
			key := partition[0]
			path = partition[1]
			key = field.KeyFromStr(key).(string)
			children := rev.GetChildren()[name]
			_, childRev := n.findRevByKey(children, field.Key, key)
			childNode := childRev.GetNode()
			return childNode.getProxy(path, root, fullPath, exclusive)
		}
		log.Error("cannot index into container with no keys")
	} else {
		childRev := rev.GetChildren()[name][0]
		childNode := childRev.GetNode()
		return childNode.getProxy(path, root, fullPath, exclusive)
	}

	return nil
}

func (n *Node) makeProxy(root *Root, fullPath string, exclusive bool) *Proxy {
	if n.Proxy == nil {
		n.Proxy = NewProxy(root, n, fullPath, exclusive)
	} else {
		if n.Proxy.Exclusive {
			log.Error("node is already owned exclusively")
		}
	}
	return n.Proxy
}

func (n *Node) makeEventBus() *EventBus {
	if n.EventBus == nil {
		n.EventBus = NewEventBus()
	}
	return n.EventBus
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Persistence Loading ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

func (n *Node) LoadLatest(kvStore *Backend, hash string) {
	branch := NewBranch(n, "", nil, n.AutoPrune)
	pr := &PersistedRevision{}
	rev := pr.Load(branch, kvStore, n.Type, hash)
	n.MakeLatest(branch, rev, nil)
	n.Branches[NONE] = branch
}
