/*
 * 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-lib-go/v2/pkg/log"
	"github.com/opencord/voltha-lib-go/v2/pkg/probe"
)

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

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

// Create the routing proxy
func NewArouterProxy(conf *Configuration, p *probe.Probe) (*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
	}

	p.UpdateStatus("affinity-router-proxy", probe.ServiceStatusRunning)
	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
		}
	}()
}
