/*
 * 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 (
	"github.com/opencord/voltha-lib-go/pkg/common/log"
	"github.com/opencord/voltha-protos/go/voltha"
	"runtime/debug"
	"sync"
)

type ModelTestConfig struct {
	Root      *root
	Backend   *Backend
	RootProxy *Proxy
	DbPrefix  string
	DbType    string
	DbHost    string
	DbPort    int
	DbTimeout int
}

var callbackMutex sync.Mutex

func commonChanCallback(args ...interface{}) interface{} {
	log.Infof("Running common callback - arg count: %d", len(args))

	//for i := 0; i < len(args); i++ {
	//	log.Infof("ARG %d : %+v", i, args[i])
	//}

	callbackMutex.Lock()
	defer callbackMutex.Unlock()

	execDoneChan := args[1].(*chan struct{})

	// Inform the caller that the callback was executed
	if *execDoneChan != nil {
		log.Infof("Sending completion indication - stack:%s", string(debug.Stack()))
		close(*execDoneChan)
		*execDoneChan = nil
	}

	return nil
}

func commonCallback2(args ...interface{}) interface{} {
	log.Infof("Running common2 callback - arg count: %d %+v", len(args), args)

	return nil
}

func commonCallbackFunc(args ...interface{}) interface{} {
	log.Infof("Running common callback - arg count: %d", len(args))

	for i := 0; i < len(args); i++ {
		log.Infof("ARG %d : %+v", i, args[i])
	}
	execStatusFunc := args[1].(func(bool))

	// Inform the caller that the callback was executed
	execStatusFunc(true)

	return nil
}

func firstCallback(args ...interface{}) interface{} {
	name := args[0]
	id := args[1]
	log.Infof("Running first callback - name: %s, id: %s\n", name, id)
	return nil
}

func secondCallback(args ...interface{}) interface{} {
	name := args[0].(map[string]string)
	id := args[1]
	log.Infof("Running second callback - name: %s, id: %f\n", name["name"], id)
	// FIXME: the panic call seem to interfere with the logging mechanism
	//panic("Generating a panic in second callback")
	return nil
}

func thirdCallback(args ...interface{}) interface{} {
	name := args[0]
	id := args[1].(*voltha.Device)
	log.Infof("Running third callback - name: %+v, id: %s\n", name, id.Id)
	return nil
}
