/*
 * 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 (
	"encoding/json"
	"fmt"
	"github.com/opencord/voltha-go/protos/voltha"
	"testing"
	"time"
)

var (
	backend *Backend
	//rootPrefix = "service/voltha/data/core/0001"

	basePrefix  = "service/voltha/service/vcores/data/devices"
	deviceId    = "00016f13befaedcc"
	rootPrefix  = basePrefix + "/" + deviceId
	deviceProxy = "/devices/" + deviceId
)

func Test_NewRoot(t *testing.T) {
	backend = NewBackend(ETCD_KV, etcd_host, etcd_port, timeout, rootPrefix)

	//var msgClass *voltha.VolthaInstance
	var msgClass *voltha.DeviceInstance
	root := NewRoot(msgClass, backend, nil)

	start := time.Now()

	r := root.Load(msgClass)
	afterLoad := time.Now()
	fmt.Printf(">>>>>>>>>>>>> Time to Load : %f\n", afterLoad.Sub(start).Seconds())

	d := r.Node.Get(deviceProxy, "", 0, false, "")
	afterGet := time.Now()
	fmt.Printf(">>>>>>>>>>>>> Time to Load and get: %f\n", afterGet.Sub(start).Seconds())

	jr, _ := json.Marshal(r)
	fmt.Printf("Content of ROOT --> \n%s\n", jr)

	jd, _ := json.Marshal(d)
	fmt.Printf("Content of GET --> \n%s\n", jd)

}
