/*
 * 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/v2/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 SourceRouter 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 TestSourceRouterDecodeProtoFieldMissingField(t *testing.T) {
	_, routerConfig := MakeSourceRouterTestConfig()
	_, err := newRouter(routerConfig)
	assert.Nil(t, err)

	// Get the created SourceRouter 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)

	_, err = sourceRouter.decodeProtoField(loggingData, 123) // field 123 does not exist
	assert.EqualError(t, err, "At end of message, attribute 123 not found")
}

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")
}
