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

// This file implements the ArouterPoxy struct and its
// functions. The ArouterProxy is the top level object
// for the affinity router.

import (
	"github.com/opencord/voltha-go/common/log"
)

// String names for display in error messages.
var arProxy *ArouterProxy = nil

type ArouterProxy struct {
	servers map[string]*server // Defined in handler.go
	api     *ArouterApi
}

// Create the routing proxy
func NewArouterProxy(conf *Configuration) (*ArouterProxy, error) {
	arProxy = &ArouterProxy{servers: make(map[string]*server)}
	// Create all the servers listed in the configuration
	for _, s := range conf.Servers {
		if ns, err := newServer(&s); err != nil {
			log.Error("Configuration failed")
			return nil, err
		} else {
			arProxy.servers[ns.Name()] = ns
		}
	}

	// TODO: The API is not mandatory, check if it's even in the config before
	// trying to create it. If it isn't then don't bother but log a warning.
	if api, err := newApi(&conf.Api, arProxy); err != nil {
		return nil, err
	} else {
		arProxy.api = api
	}

	return arProxy, nil
}

// Start serving
func (ap *ArouterProxy) ListenAndServe() error {

	for _, srvr := range ap.servers {
		ap.serve(srvr)
	}
	ap.api.serve()

	// Just wait until we're done which only happens
	// on a signal or an error.
	err := <-doneChan

	return err
}

func (ap *ArouterProxy) serve(srvr *server) {

	// Start a serving thread
	go func() {
		srvr.running = true
		if err := srvr.proxyServer.Serve(srvr.proxyListener); err != nil {
			srvr.running = false
			log.Error(err)
			errChan <- err
		}
	}()
}
