/*
 * Portions copyright 2019-present Open Networking Foundation
 * Original copyright 2019-present Ciena Corporation
 *
 * Licensed under the Apache License, Version 2.0 (the"github.com/stretchr/testify/assert" "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 afrouter

import (
	"github.com/golang/protobuf/proto"
	"github.com/opencord/voltha-go/common/log"
	common_pb "github.com/opencord/voltha-protos/go/common"
	"github.com/stretchr/testify/assert"
	"testing"
)

const (
	SOURCE_ROUTER_PROTOFILE = "../../vendor/github.com/opencord/voltha-protos/go/voltha.pb"
)

func init() {
	log.SetDefaultLogger(log.JSON, log.DebugLevel, nil)
	log.AddPackage(log.JSON, log.WarnLevel, nil)
}

func MakeSourceRouterTestConfig() (*ConnectionConfig, *BackendConfig, *BackendClusterConfig, *RouteConfig, *RouterConfig) {
	connectionConfig := ConnectionConfig{
		Name: "ro_vcore01",
		Addr: "foo",
		Port: "123",
	}

	backendConfig := BackendConfig{
		Name:        "ro_vcore0",
		Type:        BackendSingleServer,
		Connections: []ConnectionConfig{connectionConfig},
	}

	backendClusterConfig := BackendClusterConfig{
		Name:     "ro_vcore",
		Backends: []BackendConfig{backendConfig},
	}

	routeConfig := RouteConfig{
		Name:           "logger",
		Type:           RouteTypeSource,
		RouteField:     "component_name",
		BackendCluster: "ro_vcore",
		backendCluster: &backendClusterConfig,
		Methods:        []string{"UpdateLogLevel", "GetLogLevel"},
	}

	routerConfig := RouterConfig{
		Name:         "vcore",
		ProtoService: "VolthaService",
		ProtoPackage: "voltha",
		Routes:       []RouteConfig{routeConfig},
		ProtoFile:    SOURCE_ROUTER_PROTOFILE,
	}
	return &connectionConfig, &backendConfig, &backendClusterConfig, &routeConfig, &routerConfig
}

func TestSourceRouterInit(t *testing.T) {
	_, _, _, routeConfig, routerConfig := MakeSourceRouterTestConfig()

	router, err := newSourceRouter(routerConfig, routeConfig)

	assert.NotEqual(t, router, nil)
	assert.Equal(t, err, nil)

	assert.Equal(t, router.Service(), "VolthaService")
	assert.Equal(t, router.Name(), "logger")

	cluster, err := router.BackendCluster("foo", "bar")
	assert.Equal(t, cluster, clusters["ro_vcore"])
	assert.Equal(t, err, nil)

	assert.Equal(t, router.FindBackendCluster("ro_vcore"), clusters["ro_vcore"])
	assert.Equal(t, router.ReplyHandler("foo"), nil)
}

func TestSourceRouterDecodeProtoField(t *testing.T) {
	_, _, _, routeConfig, routerConfig := MakeSourceRouterTestConfig()

	router, err := newSourceRouter(routerConfig, routeConfig)
	assert.Equal(t, err, nil)

	loggingMessage := &common_pb.Logging{Level: 1,
		PackageName:   "default",
		ComponentName: "ro_vcore0.ro_vcore01"}

	loggingData, err := proto.Marshal(loggingMessage)
	assert.Equal(t, err, nil)

	s, err := router.(SourceRouter).decodeProtoField(loggingData, 2) // field 2 is package_name
	assert.Equal(t, s, "default")

	s, err = router.(SourceRouter).decodeProtoField(loggingData, 3) // field 2 is component_name
	assert.Equal(t, s, "ro_vcore0.ro_vcore01")
}

func TestSourceRouterRoute(t *testing.T) {
	_, _, _, routeConfig, routerConfig := MakeSourceRouterTestConfig()

	router, err := newSourceRouter(routerConfig, routeConfig)
	assert.Equal(t, err, nil)

	loggingMessage := &common_pb.Logging{Level: 1,
		PackageName:   "default",
		ComponentName: "ro_vcore0.ro_vcore01"}

	loggingData, err := proto.Marshal(loggingMessage)
	assert.Equal(t, err, nil)

	sel := &requestFrame{payload: loggingData,
		err:        nil,
		methodInfo: newMethodDetails("/voltha.VolthaService/UpdateLogLevel")}

	backend, connection := router.Route(sel)

	assert.Equal(t, sel.err, nil)
	assert.NotEqual(t, backend, nil)
	assert.Equal(t, backend.name, "ro_vcore0")
	assert.NotEqual(t, connection, nil)
	assert.Equal(t, connection.name, "ro_vcore01")
}
