/*

   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 main

import (
	"flag"
	"log"
	"os"
	"os/signal"
	"strings"
	"syscall"

	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/rest"

	"k8s.io/client-go/tools/clientcmd"

	_ "k8s.io/client-go/util/workqueue"

	_ "k8s.io/api/extensions/v1beta1"

	ep "ingress-ats/endpoint"
	"ingress-ats/namespace"
	"ingress-ats/proxy"
	"ingress-ats/redis"
	w "ingress-ats/watcher"
)

var (
	apiServer          = flag.String("apiServer", "http://notfound.com/", "The kubernetes api server. It should be set if useKubeConfig is set to false. Setting to a dummy value to prevent accidental usage.")
	useKubeConfig      = flag.Bool("useKubeConfig", false, "Set to true to use kube config passed in kubeconfig arg.")
	useInClusterConfig = flag.Bool("useInClusterConfig", true, "Set to false to opt out incluster config passed in kubeconfig arg.")
	kubeconfig         = flag.String("kubeconfig", "/usr/local/etc/k8s/k8s.config", "Absolute path to the kubeconfig file. Only works if useKubeConfig is set to true.")

	certFilePath = flag.String("certFilePath", "/etc/pki/tls/certs/kube-router.pem", "Absolute path to kuberouter user cert file.")
	keyFilePath  = flag.String("keyFilePath", "/etc/pki/tls/private/kube-router-key.pem", "Absolute path to kuberouter user key file.")
	caFilePath   = flag.String("caFilePath", "/etc/pki/tls/certs/ca.pem", "Absolute path to k8s cluster ca file.")

	namespaces       = flag.String("namespaces", namespace.ALL, "Comma separated list of namespaces to watch for ingress and endpoints.")
	ignoreNamespaces = flag.String("ignoreNamespaces", "", "Comma separated list of namespaces to ignore for ingress and endpoints.")

	atsNamespace    = flag.String("atsNamespace", "default", "Name of Namespace the ATS pod resides.")
	atsIngressClass = flag.String("atsIngressClass", "", "Ingress Class of Ingress object that ATS will retrieve routing info from")
)

func init() {
	flag.Parse()
}

func main() {
	var (
		config                           *rest.Config
		err                              error
		namespaceMap, ignoreNamespaceMap map[string]bool
	)

	if *atsNamespace == "" {
		log.Panicln("Not all required args given.")
	}

	namespaceMap = make(map[string]bool)

	// default namespace to "all"
	if *namespaces != namespace.ALL {
		namespaceList := strings.Split(strings.Replace(strings.ToLower(*namespaces), " ", "", -1), ",")
		for _, namespace := range namespaceList {
			if namespace != "" {
				namespaceMap[namespace] = true
			}
		}
	}

	ignoreNamespaceMap = make(map[string]bool)

	if *ignoreNamespaces != "" {
		ignoreNamespaceList := strings.Split(strings.Replace(strings.ToLower(*ignoreNamespaces), " ", "", -1), ",")
		for _, namespace := range ignoreNamespaceList {
			if namespace != "" {
				ignoreNamespaceMap[namespace] = true
			}
		}
	}

	if *useKubeConfig {
		log.Println("Read config from ", *kubeconfig)
		/* For running outside of the cluster
		uses the current context in kubeconfig */
		config, err = clientcmd.BuildConfigFromFlags("", *kubeconfig)
		if err != nil {
			log.Panicln(err.Error())
		}
		/* for running inside the cluster */
	} else if *useInClusterConfig {
		config, err = rest.InClusterConfig()
		if err != nil {
			log.Panicln("failed to create InClusterConfig: " + err.Error())
		}
	} else {
		/* create config and set necessary parameters */
		config = &rest.Config{}
		config.Host = *apiServer
		config.CertFile = *certFilePath
		config.KeyFile = *keyFilePath
		config.CAFile = *caFilePath
	}

	/* creates the clientset */
	clientset, err := kubernetes.NewForConfig(config)
	if err != nil {
		log.Panic(err.Error())
	}

	stopChan := make(chan struct{})

	// ------------ Resolving Namespaces --------------------------------------
	nsManager := namespace.NsManager{
		NamespaceMap:       namespaceMap,
		IgnoreNamespaceMap: ignoreNamespaceMap,
	}

	nsManager.Init()

	//------------ Setting up Redis in memory Datastructure -------------------
	rClient, err := redis.Init()
	if err != nil {
		log.Panicln("Redis Error: ", err)
	}

	// IMPORTANT:
	// We're assuming ingress must be using EXTENSIONS V1BETA1 API
	// ALL services must be using CORE V1 API
	endpoint := ep.Endpoint{
		RedisClient: rClient,
		ATSManager:  &proxy.ATSManager{Namespace: *atsNamespace, IngressClass: *atsIngressClass},
		NsManager:   &nsManager,
	}

	watcher := w.Watcher{
		Cs:           clientset,
		ATSNamespace: *atsNamespace,
		Ep:           &endpoint,
		StopChan:     stopChan,
	}

	err = watcher.Watch()
	if err != nil {
		log.Panicln("Error received from watcher.Watch() :", err)
	}

	/* Program termination */
	signalChan := make(chan os.Signal, 1)
	signal.Notify(signalChan, syscall.SIGINT, syscall.SIGTERM)
	for {
		select {
		case <-signalChan:
			log.Println("Shutdown signal received, exiting...")
			close(stopChan)
			os.Exit(0)
		}
	}
}
