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

// Command line parameters and parsing
import (
	"os"
	"fmt"
	"flag"
	"path"
	"errors"
	"io/ioutil"
	"encoding/json"
	"github.com/opencord/voltha-go/common/log"
)

func ParseCmd() (*Configuration, error) {
	config := &Configuration{}
	cmdParse := flag.NewFlagSet(path.Base(os.Args[0]), flag.ContinueOnError);
	config.ConfigFile = cmdParse.String("config", "arouter.json", "The configuration file for the affinity router")
	config.LogLevel = cmdParse.Int("logLevel", 0, "The log level for the affinity router")
	config.GrpcLog = cmdParse.Bool("grpclog", false, "Enable GRPC logging")

	err := cmdParse.Parse(os.Args[1:]);
	if err != nil {
		//return err
		return nil, errors.New("Error parsing the command line");
	}
	//if(!cmdParse.Parsed()) {
	//}
	return config, nil
}

// Configuration file loading and parsing
type Configuration struct {
	ConfigFile * string
	LogLevel * int
	GrpcLog * bool
	Servers []ServerConfig `json:"servers"`
	Ports PortConfig `json:"ports"`
	ServerCertificates ServerCertConfig `json:"serverCertificates"`
	ClientCertificates ClientCertConfig `json:"clientCertificates"`
	BackendClusters []BackendClusterConfig `json:"backend_clusters"`
	Routers []RouterConfig `json:"routers"`
	Api ApiConfig
}

type RouterConfig struct {
	Name string `json:"name"`
	ProtoService string `json:"service"`
	ProtoPackage string `json:"package"`
	Routes []RouteConfig `json:"routes"`
}

type RouteConfig struct {
	Name string `json:"name"`
	Type string `json:"type"`
	ProtoFile string `json:"proto_descriptor"`
	Association string `json:"association"`
	RouteField string `json:"routing_field"`
	Methods []string `json:"methods"` // The GRPC methods to route using the route field
	NbBindingMethods []string `json:"nb_binding_methods"`
	BackendCluster string `json:"backend_cluster"`
	Binding BindingConfig `json:"binding"`
	Overrides []OverrideConfig `json:"overrides"`
	backendCluster *BackendClusterConfig
}

type BindingConfig struct {
	Type string `json:"type"`
	Field string `json:"field"`
	Method string `json:"method"`
	Association string `json:"association"`

}

type OverrideConfig struct {
	Methods []string `json:"methods"`
	Method []string `json:"method"`
	RouteField string `json:"routing_field"`
}

// Backend configuration

type BackendClusterConfig struct {
	Name string `json:"name"`
	Backends []BackendConfig `json:"backends"`
}

type BackendConfig struct {
	Name string `json:"name"`
	Type string `json:"type"`
	Association AssociationConfig `json:"association"`
	Connections []ConnectionConfig `json:"connections"`
}

type AssociationConfig struct {
	Strategy string `json:"strategy"`
	Location string `json:"location"`
	Field string `json:"field"`
}

type ConnectionConfig struct {
	Name string `json:"name"`
	Addr string `json:"addr"`
	Port string `json:"port"`
}

// Server configuration

type ServerConfig struct {
	Name string `json:"name"`
	Port uint `json:"port"`
	Addr string `json:"address"`
	Type string `json:"type"`
	Routers []RouterPackage `json:"routers"`
	routers map[string]*RouterConfig
}

type RouterPackage struct {
	Router string `json:"router"`
	Package string `json:"package"`
}

// Port configuration
type PortConfig struct {
	GrpcPort uint `json:"grpcPort"`
	StreamingGrpcPort uint `json:"streamingGrpcPort"`
	TlsGrpcPort uint `json:"tlsGrpcPort"`
	TlsStreamingGrpcPort uint `json:"tlsStreamingGrpcPort"`
	ControlPort uint `json:"controlPort"`
}

// Server Certificate configuration
type ServerCertConfig struct {
	GrpcCert string `json:"grpcCertificate"`	// File path to the certificate file
	GrpcKey string `json:"grpcKey"`			// File path to the key file
	GrpcCsr string `json:"grpcCsr"`			// File path to the CSR file
}

// Client Certificate configuration
type ClientCertConfig struct {
	GrpcCert string `json:"grpcCertificate"`	// File path to the certificate file
	GrpcKey string `json:"grpcKey"`			// File path to the key file
	GrpcCsr string `json:"grpcCsr"`			// File path to the CSR file
}

// Api configuration
type ApiConfig struct {
	Addr string `json:"address"`
	Port uint `json:"port"`
}

func (conf * Configuration) LoadConfig() error {

	configF, err := os.Open(*conf.ConfigFile);
	log.Info("Loading configuration from: ", *conf.ConfigFile)
	if err != nil {
		log.Error(err)
		return err
	}

	defer configF.Close()

	configBytes, err := ioutil.ReadAll(configF)
	if err != nil {
		log.Error(err)
		return err
	}

	json.Unmarshal(configBytes, conf)

	// Now resolve references to different config objects in the
	// config file. Currently there are 2 possible references
	// to resolve: referecnes to routers in the servers, and
	// references to backend_cluster in the routers.

	// Resolve router references for the servers
	log.Debug("Resolving references in the config file");
	for k,_ := range conf.Servers {
		//s.routers =make(map[string]*RouterConfig)
		conf.Servers[k].routers = make(map[string]*RouterConfig)
		for _,rPkg := range conf.Servers[k].Routers {
			var found bool = false
			// Locate the router "r" in the top lever Routers array
			log.Debugf("Resolving router reference to router '%s' from server '%s'",rPkg.Router, conf.Servers[k].Name)
			for rk, _ := range conf.Routers {
				if conf.Routers[rk].Name == rPkg.Router && !found {
					log.Debugf("Reference to router '%s' found for package '%s'", rPkg.Router, rPkg.Package)
					conf.Servers[k].routers[rPkg.Package] = &conf.Routers[rk]
					found = true
				} else if conf.Routers[rk].Name == rPkg.Router && found {
					if _,ok := conf.Servers[k].routers[rPkg.Package]; !ok {
						log.Debugf("Reference to router '%s' found for package '%s'", rPkg.Router, rPkg.Package)
						conf.Servers[k].routers[rPkg.Package] = &conf.Routers[rk]
					} else {
						err := errors.New(fmt.Sprintf("Duplicate router '%s' defined for package '%s'",rPkg.Package))
						log.Error(err)
						return err
					}
				}
			}
			if !found {
				err := errors.New(fmt.Sprintf("Router %s for server %s not found in config", conf.Servers[k].Name, rPkg.Router))
				log.Error(err)
				return err
			}
		}
	}

	// Resolve backend references for the routers
	for rk,rv := range conf.Routers {
		for rtk,rtv := range rv.Routes {
			var found bool = false
			log.Debugf("Resolving backend reference to %s from router %s",rtv.BackendCluster, rv.Name)
			for bek,bev := range conf.BackendClusters {
				log.Debugf("Checking cluster %s", conf.BackendClusters[bek].Name)
				if rtv.BackendCluster == bev.Name && !found {
					conf.Routers[rk].Routes[rtk].backendCluster = &conf.BackendClusters[bek]
					found = true
				} else if rtv.BackendCluster == bev.Name && found {
					err := errors.New(fmt.Sprintf("Duplicate backend defined, %s",conf.BackendClusters[bek].Name))
					log.Error(err)
					return err
				}
			}
			if !found  {
				err := errors.New(fmt.Sprintf("Backend %s for router %s not found in config",
									rtv.BackendCluster, rv.Name))
				log.Error(err)
				return err
			}
		}
	}


	return nil
}
