package main

import (
	"flag"
	"fmt"
	"net"
	"os"
	"os/signal"
	"strings"
	"syscall"

	"github.com/gologme/log"

	"github.com/zhoreeq/meshname/src/meshname"
)

func parseNetworks(networksconf string) (map[string]*net.IPNet, error) {
	networks := make(map[string]*net.IPNet)
	for _, item := range strings.Split(networksconf, ",") {
		if tokens := strings.SplitN(item, "=", 2); len(tokens) == 2 {
			if _, validSubnet, err := net.ParseCIDR(tokens[1]); err == nil {
				networks[tokens[0]] = validSubnet
			} else {
				return nil, err
			}
		}
	}
	return networks, nil
}

func main() {
	genconf := flag.String("genconf", "", "generate a new config for IP address")
	subdomain := flag.String("subdomain", "meshname.", "subdomain used to generate config")
	useconffile := flag.String("useconffile", "", "run daemon with a config file")
	listenAddr := flag.String("listenaddr", "[::1]:53535", "address to listen on")
	networksconf := flag.String("networks", "ygg=200::/7,cjd=fc00::/8,meshname=::/0", "TLD=subnet list separated by comma")
	debug := flag.Bool("debug", false, "enable debug logging")
	flag.Parse()

	var logger *log.Logger
	logger = log.New(os.Stdout, "", log.Flags())

	logger.EnableLevel("error")
	logger.EnableLevel("warn")
	logger.EnableLevel("info")
	if *debug {
		logger.EnableLevel("debug")
	}

	if *genconf != "" {
		if conf, err := meshname.GenConf(*genconf, *subdomain); err == nil {
			fmt.Println(conf)
		} else {
			logger.Errorln(err)
		}
		return
	}


	s := new(meshname.MeshnameServer)
	s.Init(logger, *listenAddr)

	if networks, err := parseNetworks(*networksconf); err == nil {
		s.SetNetworks(networks)
	} else {
		logger.Errorln(err)
	}

	if *useconffile != "" {
		s.LoadConfig(*useconffile)
	}

	s.Start()

	c := make(chan os.Signal, 1)
	r := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt, syscall.SIGTERM)
	signal.Notify(r, os.Interrupt, syscall.SIGHUP)
	defer s.Stop()
	for {
		select {
		case _ = <-c:
			return
		case _ = <-r:
			if *useconffile != "" {
				s.Stop()
				s.LoadConfig(*useconffile)
				s.Start()
			}
		}
	}
}