package main

import "io"
import "os"
import "log"
import "time"
import "hnakra/router"
import "hnakra/rotate"
import "hnakra/daemon"
import "hnakra/routines"
import "hnakra/router/rcon"
import "hnakra/router/config"
import "hnakra/cmd/hn-router/srvhttps"
import "hnakra/cmd/hn-router/srvhnakra"

const banner = "\n" +
"            -=\\\n" +
"__.        __|.\\___\n" +
" - ``.__.-`        ```'-.    |  | |\\ | |\\   | / |''| |\\\n" +
"  `-,                u   `.  |--| | \\| |-\\  |<  |-<  |-\\\n" +
" ,-'  ,````            VVv   |  | |  | |  \\ | \\ |  \\ |  \\\n" +
"/___-'  ````--//----'''``\n" +
"            |/               DISTRIBUTED HOLANET SERVER ROUTER\n" +
"           '/"

func main () {
	// set up logging
	logDir := os.Getenv("HNAKRA_LOG_DIR")
	if logDir != "" {
		logger, err := rotate.New(logDir)
		if err != nil { log.Fatal("cannot access log dir:", err) }
		log.SetOutput(logger)
	}
	rcon := rcon.New("/debug/rcon")
	originalWriter := log.Writer()
	log.SetOutput(io.MultiWriter(originalWriter, rcon))
	log.Println(banner)

	// load config
	log.Println("... loading config")
	conf, err := config.File("/etc/hnakra/hnakra.conf")
	if err != nil { log.Fatal(err) }
	log.Println("(i) users:")
	conf.OverUsers(func (name string, user config.User) bool {
		log.Println("    -", name)
		return true
	})
	log.Println("(i) aliases:")
	if conf.AliasFallback() != "" {
		log.Println("    - (fallback) ->", conf.AliasFallback())
	}
	conf.OverAliases(func (alias, target string) bool{
		log.Println("    -", alias, "->", target)
		return true
	})
	rcon.SetConfig(conf)

	// set up servers
	log.Println("... starting up")
	manager   := routines.Manager { RestartDeadline: time.Second * 8 }
	rout      := router.New(conf)
	srvhnakra := &srvhnakra.Server { Config: conf, Router:  rout }
	manager.Append(srvhnakra)
	if conf.HTTPSEnable() {
		srvhttps := &srvhttps.Server { Config: conf, Handler: rout }
		manager.Append(srvhttps)
	}

	// set up rcon
	rcon.SetRouter(rout)
	if conf.RconEnable() {
		err = rout.HTTPMux().Handle("@/debug/rcon/", rcon)
		if err != nil { log.Fatalln("XXX", err) }
	} else {
		log.SetOutput(originalWriter)
	}

	// be a daemon
	daemon.ShutdownOnSigint(&manager)
	pidfile := daemon.PidFile(os.Getenv("HNAKRA_PIDFILE"))
	if !pidfile.Empty() {
		err := pidfile.Start()
		if err != nil { log.Println("!!! could not write pid:", err) }
		defer func () {
			err := pidfile.Close()
			if err != nil { log.Println("!!! could not delete pidfile:", err) }
		} ()
	}

	// run servers
	err = manager.Run()
	if err != nil { log.Println("XXX", err) }
}
