/*
 * 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"
	common_pb "github.com/opencord/voltha-protos/go/common"
	"github.com/stretchr/testify/assert"
	"testing"
)

func MakeSourceRouterTestConfig() (*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:    TEST_PROTOFILE,
	}
	return &routeConfig, &routerConfig
}

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

	router, err := newSourceRouter(routerConfig, routeConfig)

	assert.NotNil(t, router)
	assert.Nil(t, err)

	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.Nil(t, err)

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

func TestSourceRouterDecodeProtoField(t *testing.T) {
	_, routerConfig := MakeSourceRouterTestConfig()
	_, err := newRouter(routerConfig)
	assert.Nil(t, err)

	// Get the created AffinityRouter so we can inspect its state
	sourceRouter := allRouters["vcorelogger"].(SourceRouter)

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

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

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

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

func TestSourceRouterRoute(t *testing.T) {
	_, routerConfig := MakeSourceRouterTestConfig()
	_, err := newRouter(routerConfig)
	assert.Nil(t, err)

	// Get the created AffinityRouter so we can inspect its state
	sourceRouter := allRouters["vcorelogger"].(SourceRouter)

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

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

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

	backend, connection := sourceRouter.Route(sel)

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