/*
 * 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 (
	"context"
	"crypto/md5"
	"errors"
	"fmt"
	"github.com/google/uuid"
	"github.com/opencord/voltha-lib-go/pkg/common/log"
	"reflect"
	"runtime"
	"strings"
	"sync"
)

// OperationContext holds details on the information used during an operation
type OperationContext struct {
	Path      string
	Data      interface{}
	FieldName string
	ChildKey  string
}

// NewOperationContext instantiates a new OperationContext structure
func NewOperationContext(path string, data interface{}, fieldName string, childKey string) *OperationContext {
	oc := &OperationContext{
		Path:      path,
		Data:      data,
		FieldName: fieldName,
		ChildKey:  childKey,
	}
	return oc
}

// Update applies new data to the context structure
func (oc *OperationContext) Update(data interface{}) *OperationContext {
	oc.Data = data
	return oc
}

// Proxy holds the information for a specific location with the data model
type Proxy struct {
	mutex      sync.RWMutex
	Root       *root
	Node       *node
	ParentNode *node
	Path       string
	FullPath   string
	Exclusive  bool
	Callbacks  map[CallbackType]map[string]*CallbackTuple
	operation  ProxyOperation
}

// NewProxy instantiates a new proxy to a specific location
func NewProxy(root *root, node *node, parentNode *node, path string, fullPath string, exclusive bool) *Proxy {
	callbacks := make(map[CallbackType]map[string]*CallbackTuple)
	if fullPath == "/" {
		fullPath = ""
	}
	p := &Proxy{
		Root:       root,
		Node:       node,
		ParentNode: parentNode,
		Exclusive:  exclusive,
		Path:       path,
		FullPath:   fullPath,
		Callbacks:  callbacks,
	}
	return p
}

// GetRoot returns the root attribute of the proxy
func (p *Proxy) GetRoot() *root {
	return p.Root
}

// getPath returns the path attribute of the proxy
func (p *Proxy) getPath() string {
	return p.Path
}

// getFullPath returns the full path attribute of the proxy
func (p *Proxy) getFullPath() string {
	return p.FullPath
}

// getCallbacks returns the full list of callbacks associated to the proxy
func (p *Proxy) getCallbacks(callbackType CallbackType) map[string]*CallbackTuple {
	p.mutex.RLock()
	defer p.mutex.RUnlock()

	if p != nil {
		if cb, exists := p.Callbacks[callbackType]; exists {
			return cb
		}
	} else {
		log.Debugw("proxy-is-nil", log.Fields{"callback-type": callbackType.String()})
	}
	return nil
}

// getCallback returns a specific callback matching the type and function hash
func (p *Proxy) getCallback(callbackType CallbackType, funcHash string) *CallbackTuple {
	p.mutex.Lock()
	defer p.mutex.Unlock()
	if tuple, exists := p.Callbacks[callbackType][funcHash]; exists {
		return tuple
	}
	return nil
}

// setCallbacks applies a callbacks list to a type
func (p *Proxy) setCallbacks(callbackType CallbackType, callbacks map[string]*CallbackTuple) {
	p.mutex.Lock()
	defer p.mutex.Unlock()
	p.Callbacks[callbackType] = callbacks
}

// setCallback applies a callback to a type and hash value
func (p *Proxy) setCallback(callbackType CallbackType, funcHash string, tuple *CallbackTuple) {
	p.mutex.Lock()
	defer p.mutex.Unlock()
	p.Callbacks[callbackType][funcHash] = tuple
}

// DeleteCallback removes a callback matching the type and hash
func (p *Proxy) DeleteCallback(callbackType CallbackType, funcHash string) {
	p.mutex.Lock()
	defer p.mutex.Unlock()
	delete(p.Callbacks[callbackType], funcHash)
}

// CallbackType is an enumerated value to express when a callback should be executed
type ProxyOperation uint8

// Enumerated list of callback types
const (
	PROXY_NONE ProxyOperation = iota
	PROXY_GET
	PROXY_LIST
	PROXY_ADD
	PROXY_UPDATE
	PROXY_REMOVE
	PROXY_CREATE
	PROXY_WATCH
)

var proxyOperationTypes = []string{
	"PROXY_NONE",
	"PROXY_GET",
	"PROXY_LIST",
	"PROXY_ADD",
	"PROXY_UPDATE",
	"PROXY_REMOVE",
	"PROXY_CREATE",
	"PROXY_WATCH",
}

func (t ProxyOperation) String() string {
	return proxyOperationTypes[t]
}

func (p *Proxy) GetOperation() ProxyOperation {
	p.mutex.RLock()
	defer p.mutex.RUnlock()
	return p.operation
}

func (p *Proxy) SetOperation(operation ProxyOperation) {
	p.mutex.Lock()
	defer p.mutex.Unlock()
	p.operation = operation
}

// parseForControlledPath verifies if a proxy path matches a pattern
// for locations that need to be access controlled.
func (p *Proxy) parseForControlledPath(path string) (pathLock string, controlled bool) {
	// TODO: Add other path prefixes that may need control
	if strings.HasPrefix(path, "/devices") ||
		strings.HasPrefix(path, "/logical_devices") ||
		strings.HasPrefix(path, "/adapters") {

		split := strings.SplitN(path, "/", -1)
		switch len(split) {
		case 2:
			controlled = false
			pathLock = ""
			break
		case 3:
			fallthrough
		default:
			pathLock = fmt.Sprintf("%s/%s", split[1], split[2])
			controlled = true
		}
	}
	return pathLock, controlled
}

// List will retrieve information from the data model at the specified path location
// A list operation will force access to persistence storage
func (p *Proxy) List(ctx context.Context, path string, depth int, deep bool, txid string) interface{} {
	var effectivePath string
	if path == "/" {
		effectivePath = p.getFullPath()
	} else {
		effectivePath = p.getFullPath() + path
	}

	pathLock, controlled := p.parseForControlledPath(effectivePath)

	p.SetOperation(PROXY_LIST)
	defer p.SetOperation(PROXY_NONE)

	log.Debugw("proxy-list", log.Fields{
		"path":       path,
		"effective":  effectivePath,
		"pathLock":   pathLock,
		"controlled": controlled,
		"operation":  p.GetOperation(),
	})

	rv := p.GetRoot().List(ctx, path, "", depth, deep, txid)

	return rv
}

// Get will retrieve information from the data model at the specified path location
func (p *Proxy) Get(ctx context.Context, path string, depth int, deep bool, txid string) interface{} {
	var effectivePath string
	if path == "/" {
		effectivePath = p.getFullPath()
	} else {
		effectivePath = p.getFullPath() + path
	}

	pathLock, controlled := p.parseForControlledPath(effectivePath)

	p.SetOperation(PROXY_GET)
	defer p.SetOperation(PROXY_NONE)

	log.Debugw("proxy-get", log.Fields{
		"path":       path,
		"effective":  effectivePath,
		"pathLock":   pathLock,
		"controlled": controlled,
		"operation":  p.GetOperation(),
	})

	rv := p.GetRoot().Get(ctx, path, "", depth, deep, txid)

	return rv
}

// Update will modify information in the data model at the specified location with the provided data
func (p *Proxy) Update(ctx context.Context, path string, data interface{}, strict bool, txid string) interface{} {
	if !strings.HasPrefix(path, "/") {
		log.Errorf("invalid path: %s", path)
		return nil
	}
	var fullPath string
	var effectivePath string
	if path == "/" {
		fullPath = p.getPath()
		effectivePath = p.getFullPath()
	} else {
		fullPath = p.getPath() + path
		effectivePath = p.getFullPath() + path
	}

	pathLock, controlled := p.parseForControlledPath(effectivePath)

	p.SetOperation(PROXY_UPDATE)
	defer p.SetOperation(PROXY_NONE)

	log.Debugw("proxy-update", log.Fields{
		"path":       path,
		"effective":  effectivePath,
		"full":       fullPath,
		"pathLock":   pathLock,
		"controlled": controlled,
		"operation":  p.GetOperation(),
	})

	if p.GetRoot().KvStore != nil {
		p.GetRoot().KvStore.Client.Reserve(pathLock+"_", uuid.New().String(), ReservationTTL)
		defer p.GetRoot().KvStore.Client.ReleaseReservation(pathLock + "_")
	}

	result := p.GetRoot().Update(ctx, fullPath, data, strict, txid, nil)

	if result != nil {
		return result.GetData()
	}

	return nil
}

// AddWithID will insert new data at specified location.
// This method also allows the user to specify the ID of the data entry to ensure
// that access control is active while inserting the information.
func (p *Proxy) AddWithID(ctx context.Context, path string, id string, data interface{}, txid string) interface{} {
	if !strings.HasPrefix(path, "/") {
		log.Errorf("invalid path: %s", path)
		return nil
	}
	var fullPath string
	var effectivePath string
	if path == "/" {
		fullPath = p.getPath()
		effectivePath = p.getFullPath()
	} else {
		fullPath = p.getPath() + path
		effectivePath = p.getFullPath() + path + "/" + id
	}

	pathLock, controlled := p.parseForControlledPath(effectivePath)

	p.SetOperation(PROXY_ADD)
	defer p.SetOperation(PROXY_NONE)

	log.Debugw("proxy-add-with-id", log.Fields{
		"path":       path,
		"effective":  effectivePath,
		"full":       fullPath,
		"pathLock":   pathLock,
		"controlled": controlled,
		"operation":  p.GetOperation(),
	})

	if p.GetRoot().KvStore != nil {
		p.GetRoot().KvStore.Client.Reserve(pathLock+"_", uuid.New().String(), ReservationTTL)
		defer p.GetRoot().KvStore.Client.ReleaseReservation(pathLock + "_")
	}

	result := p.GetRoot().Add(ctx, fullPath, data, txid, nil)

	if result != nil {
		return result.GetData()
	}

	return nil
}

// Add will insert new data at specified location.
func (p *Proxy) Add(ctx context.Context, path string, data interface{}, txid string) interface{} {
	if !strings.HasPrefix(path, "/") {
		log.Errorf("invalid path: %s", path)
		return nil
	}
	var fullPath string
	var effectivePath string
	if path == "/" {
		fullPath = p.getPath()
		effectivePath = p.getFullPath()
	} else {
		fullPath = p.getPath() + path
		effectivePath = p.getFullPath() + path
	}

	pathLock, controlled := p.parseForControlledPath(effectivePath)

	p.SetOperation(PROXY_ADD)
	defer p.SetOperation(PROXY_NONE)

	log.Debugw("proxy-add", log.Fields{
		"path":       path,
		"effective":  effectivePath,
		"full":       fullPath,
		"pathLock":   pathLock,
		"controlled": controlled,
		"operation":  p.GetOperation(),
	})

	if p.GetRoot().KvStore != nil {
		p.GetRoot().KvStore.Client.Reserve(pathLock+"_", uuid.New().String(), ReservationTTL)
		defer p.GetRoot().KvStore.Client.ReleaseReservation(pathLock + "_")
	}

	result := p.GetRoot().Add(ctx, fullPath, data, txid, nil)

	if result != nil {
		return result.GetData()
	}

	return nil
}

// Remove will delete an entry at the specified location
func (p *Proxy) Remove(ctx context.Context, path string, txid string) interface{} {
	if !strings.HasPrefix(path, "/") {
		log.Errorf("invalid path: %s", path)
		return nil
	}
	var fullPath string
	var effectivePath string
	if path == "/" {
		fullPath = p.getPath()
		effectivePath = p.getFullPath()
	} else {
		fullPath = p.getPath() + path
		effectivePath = p.getFullPath() + path
	}

	pathLock, controlled := p.parseForControlledPath(effectivePath)

	p.SetOperation(PROXY_REMOVE)
	defer p.SetOperation(PROXY_NONE)

	log.Debugw("proxy-remove", log.Fields{
		"path":       path,
		"effective":  effectivePath,
		"full":       fullPath,
		"pathLock":   pathLock,
		"controlled": controlled,
		"operation":  p.GetOperation(),
	})

	if p.GetRoot().KvStore != nil {
		p.GetRoot().KvStore.Client.Reserve(pathLock+"_", uuid.New().String(), ReservationTTL)
		defer p.GetRoot().KvStore.Client.ReleaseReservation(pathLock + "_")
	}

	result := p.GetRoot().Remove(ctx, fullPath, txid, nil)

	if result != nil {
		return result.GetData()
	}

	return nil
}

// CreateProxy to interact with specific path directly
func (p *Proxy) CreateProxy(ctx context.Context, path string, exclusive bool) *Proxy {
	if !strings.HasPrefix(path, "/") {
		log.Errorf("invalid path: %s", path)
		return nil
	}

	var fullPath string
	var effectivePath string
	if path == "/" {
		fullPath = p.getPath()
		effectivePath = p.getFullPath()
	} else {
		fullPath = p.getPath() + path
		effectivePath = p.getFullPath() + path
	}

	pathLock, controlled := p.parseForControlledPath(effectivePath)

	p.SetOperation(PROXY_CREATE)
	defer p.SetOperation(PROXY_NONE)

	log.Debugw("proxy-create", log.Fields{
		"path":       path,
		"effective":  effectivePath,
		"full":       fullPath,
		"pathLock":   pathLock,
		"controlled": controlled,
		"operation":  p.GetOperation(),
	})

	if p.GetRoot().KvStore != nil {
		p.GetRoot().KvStore.Client.Reserve(pathLock+"_", uuid.New().String(), ReservationTTL)
		defer p.GetRoot().KvStore.Client.ReleaseReservation(pathLock + "_")
	}

	return p.GetRoot().CreateProxy(ctx, fullPath, exclusive)
}

// OpenTransaction creates a new transaction branch to isolate operations made to the data model
func (p *Proxy) OpenTransaction() *Transaction {
	txid := p.GetRoot().MakeTxBranch()
	return NewTransaction(p, txid)
}

// commitTransaction will apply and merge modifications made in the transaction branch to the data model
func (p *Proxy) commitTransaction(txid string) {
	p.GetRoot().FoldTxBranch(txid)
}

// cancelTransaction will terminate a transaction branch along will all changes within it
func (p *Proxy) cancelTransaction(txid string) {
	p.GetRoot().DeleteTxBranch(txid)
}

// CallbackFunction is a type used to define callback functions
type CallbackFunction func(args ...interface{}) interface{}

// CallbackTuple holds the function and arguments details of a callback
type CallbackTuple struct {
	callback CallbackFunction
	args     []interface{}
}

// Execute will process the a callback with its provided arguments
func (tuple *CallbackTuple) Execute(contextArgs []interface{}) interface{} {
	args := []interface{}{}

	for _, ta := range tuple.args {
		args = append(args, ta)
	}

	if contextArgs != nil {
		for _, ca := range contextArgs {
			args = append(args, ca)
		}
	}

	return tuple.callback(args...)
}

// RegisterCallback associates a callback to the proxy
func (p *Proxy) RegisterCallback(callbackType CallbackType, callback CallbackFunction, args ...interface{}) {
	if p.getCallbacks(callbackType) == nil {
		p.setCallbacks(callbackType, make(map[string]*CallbackTuple))
	}
	funcName := runtime.FuncForPC(reflect.ValueOf(callback).Pointer()).Name()
	log.Debugf("value of function: %s", funcName)
	funcHash := fmt.Sprintf("%x", md5.Sum([]byte(funcName)))[:12]

	p.setCallback(callbackType, funcHash, &CallbackTuple{callback, args})
}

// UnregisterCallback removes references to a callback within a proxy
func (p *Proxy) UnregisterCallback(callbackType CallbackType, callback CallbackFunction, args ...interface{}) {
	if p.getCallbacks(callbackType) == nil {
		log.Errorf("no such callback type - %s", callbackType.String())
		return
	}

	funcName := runtime.FuncForPC(reflect.ValueOf(callback).Pointer()).Name()
	funcHash := fmt.Sprintf("%x", md5.Sum([]byte(funcName)))[:12]

	log.Debugf("value of function: %s", funcName)

	if p.getCallback(callbackType, funcHash) == nil {
		log.Errorf("function with hash value: '%s' not registered with callback type: '%s'", funcHash, callbackType)
		return
	}

	p.DeleteCallback(callbackType, funcHash)
}

func (p *Proxy) invoke(callback *CallbackTuple, context []interface{}) (result interface{}, err error) {
	defer func() {
		if r := recover(); r != nil {
			errStr := fmt.Sprintf("callback error occurred: %+v", r)
			err = errors.New(errStr)
			log.Error(errStr)
		}
	}()

	result = callback.Execute(context)

	return result, err
}

// InvokeCallbacks executes all callbacks associated to a specific type
func (p *Proxy) InvokeCallbacks(args ...interface{}) (result interface{}) {
	callbackType := args[0].(CallbackType)
	proceedOnError := args[1].(bool)
	context := args[2:]

	var err error

	if callbacks := p.getCallbacks(callbackType); callbacks != nil {
		p.mutex.Lock()
		for _, callback := range callbacks {
			if result, err = p.invoke(callback, context); err != nil {
				if !proceedOnError {
					log.Info("An error occurred.  Stopping callback invocation")
					break
				}
				log.Info("An error occurred.  Invoking next callback")
			}
		}
		p.mutex.Unlock()
	}

	return result
}
