/*
 * 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 afrouter

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

var allRouters = make(map[string]Router)

// The router interface
type Router interface {
	Name() string

	// Route() returns a backend and a connection. The connection is optional and if unspecified, then any
	// connection on the backend may be used.
	Route(interface{}) (*backend, *connection)

	Service() string
	IsStreaming(string) (bool, bool)
	BackendCluster(string, string) (*cluster, error)
	FindBackendCluster(string) *cluster
	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) {
	switch config.Type {
	case RouteTypeRpcAffinityMessage:
		r, err := newAffinityRouter(rconf, config)
		if err == nil {
			allRouters[rconf.Name+config.Name] = r
		}
		return r, err
	case RouteTypeBinding:
		r, err := newBindingRouter(rconf, config)
		if err == nil {
			allRouters[rconf.Name+config.Name] = r
		}
		return r, err
	case RouteTypeRoundRobin:
		r, err := newRoundRobinRouter(rconf, config)
		if err == nil {
			allRouters[rconf.Name+config.Name] = r
		}
		return r, err
	case RouteTypeSource:
		r, err := newSourceRouter(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))
	}
}
