/*
 * 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.
 */
// gRPC affinity router with active/active backends

package afrouter

import (
	"errors"
	"fmt"
	"google.golang.org/grpc"
)

const (
	RT_RPC_AFFINITY_MESSAGE = iota + 1
	RT_RPC_AFFINITY_HEADER  = iota + 1
	RT_BINDING              = iota + 1
	RT_ROUND_ROBIN          = iota + 1
)

// String names for display in error messages.
var rTypeNames = []string{"", "rpc_affinity_message", "rpc_affinity_header", "binding", "round_robin"}
var rAssnNames = []string{"", "round_robin"}

var allRouters map[string]Router = make(map[string]Router)

// The router interface
type Router interface {
	Name() string
	Route(interface{}) *backend
	Service() string
	BackendCluster(string, string) (*backendCluster, error)
	FindBackendCluster(string) *backendCluster
	ReplyHandler(interface{}) error
	GetMetaKeyVal(serverStream grpc.ServerStream) (string, string, error)
}

func newRouter(config *RouterConfig) (Router, error) {
	r, err := newMethodRouter(config)
	if err == nil {
		allRouters[r.Name()] = r
	}
	return r, err
}

func newSubRouter(rconf *RouterConfig, config *RouteConfig) (Router, error) {
	idx := strIndex(rTypeNames, config.Type)
	switch idx {
	case RT_RPC_AFFINITY_MESSAGE:
		r, err := newAffinityRouter(rconf, config)
		if err == nil {
			allRouters[rconf.Name+config.Name] = r
		}
		return r, err
	case RT_BINDING:
		r, err := newBindingRouter(rconf, config)
		if err == nil {
			allRouters[rconf.Name+config.Name] = r
		}
		return r, err
	case RT_ROUND_ROBIN:
		r, err := newRoundRobinRouter(rconf, config)
		if err == nil {
			allRouters[rconf.Name+config.Name] = r
		}
		return r, err
	default:
		return nil, errors.New(fmt.Sprintf("Internal error, undefined router type: %s", config.Type))
	}
}
