package main

import (
	"fmt"
	"os"
	"os/signal"
	"syscall"
	"time"

	"github.com/flashmob/go-guerrilla"
	"github.com/flashmob/go-guerrilla/backends"
	"github.com/flashmob/go-guerrilla/log"

	// Choose iconv or mail/encoding package which uses golang.org/x/net/html/charset
	//_ "github.com/flashmob/go-guerrilla/mail/iconv"
	_ "github.com/flashmob/go-guerrilla/mail/encoding"

	"github.com/spf13/cobra"

	_ "github.com/go-sql-driver/mysql"

	"gomodules.avm99963.com/hichip2mqtt/mqtt_processor"
)

const (
	defaultPidFile = "/var/run/hichipbridge.pid"
)

var (
	configPath string
	pidFile    string

	serveCmd = &cobra.Command{
		Use:   "serve",
		Short: "start the daemon and start all available SMTP servers",
		Run:   serve,
	}

	signalChannel = make(chan os.Signal, 1) // for trapping SIGHUP and friends
	mainlog       log.Logger

	d guerrilla.Daemon
)

func init() {
	// log to stderr on startup
	var err error
	mainlog, err = log.GetLogger(log.OutputStderr.String(), log.InfoLevel.String())
	if err != nil && mainlog != nil {
		mainlog.WithError(err).Errorf("Failed creating a logger to %s", log.OutputStderr)
	}
	cfgFile := "config.json"
	serveCmd.PersistentFlags().StringVarP(&configPath, "config", "c",
		cfgFile, "Path to the configuration file")
	// intentionally didn't specify default pidFile; value from config is used if flag is empty
	serveCmd.PersistentFlags().StringVarP(&pidFile, "pidFile", "p",
		"", "Path to the pid file")
	rootCmd.AddCommand(serveCmd)
}

func sigHandler() {
	signal.Notify(signalChannel,
		syscall.SIGHUP,
		syscall.SIGTERM,
		syscall.SIGQUIT,
		syscall.SIGINT,
		syscall.SIGKILL,
		syscall.SIGUSR1,
		os.Kill,
	)
	for sig := range signalChannel {
		if sig == syscall.SIGHUP {
			if ac, err := readConfig(configPath, pidFile); err == nil {
				_ = d.ReloadConfig(*ac)
			} else {
				mainlog.WithError(err).Error("Could not reload config")
			}
		} else if sig == syscall.SIGUSR1 {
			if err := d.ReopenLogs(); err != nil {
				mainlog.WithError(err).Error("reopening logs failed")
			}
		} else if sig == syscall.SIGTERM || sig == syscall.SIGQUIT || sig == syscall.SIGINT || sig == os.Kill {
			mainlog.Infof("Shutdown signal caught")
			go func() {
				select {
				// exit if graceful shutdown not finished in 60 sec.
				case <-time.After(time.Second * 60):
					mainlog.Error("graceful shutdown timed out")
					os.Exit(1)
				}
			}()
			d.Shutdown()
			mainlog.Infof("Shutdown completed, exiting.")
			return
		} else {
			mainlog.Infof("Shutdown, unknown signal caught")
			return
		}
	}
}

func serve(cmd *cobra.Command, args []string) {
	logVersion()
	d = guerrilla.Daemon{Logger: mainlog}
	d.AddProcessor("MQTT", mqtt_processor.Processor)

	c, err := readConfig(configPath, pidFile)
	if err != nil {
		mainlog.WithError(err).Fatal("Error while reading config")
	}
	_ = d.SetConfig(*c)

	// Check that max clients is not greater than system open file limit.
	if ok, maxClients, fileLimit := guerrilla.CheckFileLimit(c); !ok {
		mainlog.Fatalf("Combined max clients for all servers (%d) is greater than open file limit (%d). "+
			"Please increase your open file limit or decrease max clients.", maxClients, fileLimit)
	}

	err = d.Start()
	if err != nil {
		mainlog.WithError(err).Error("Error(s) when creating new server(s)")
		os.Exit(1)
	}
	sigHandler()

}

func lookupPrefixedEnv(coreName string) (string, error) {
	name := "HICHIPBRIDGE_" + coreName
	v, ok := os.LookupEnv(name)
	if !ok {
		return v, fmt.Errorf("Environment variable %s isn't set", name)
	}

	return v, nil
}

// ReadConfig is called at startup, or when a SIG_HUP is caught
func readConfig(path string, pidFile string) (*guerrilla.AppConfig, error) {
	// Environment variables where some settings are configured (without the prefix "HICHIPBRIDGE_"):
	envNames := []string{
		"SMTP_HOST",
		"MQTT_BROKER",
		"MQTT_CLIENTID",
		"MQTT_USERNAME",
		"MQTT_PASSWORD",
		"MQTT_TOPIC",
		"EMAIL_TOKEN",
	}

	// Load in the config.
	appConfig, err := d.LoadConfig(path)
	if err != nil {
		return &appConfig, fmt.Errorf("could not read config file: %s", err.Error())
	}

	// override config pidFile with with flag from the command line
	if len(pidFile) > 0 {
		appConfig.PidFile = pidFile
	} else if len(appConfig.PidFile) == 0 {
		appConfig.PidFile = defaultPidFile
	}
	if verbose {
		appConfig.LogLevel = "debug"
	}

	// Override compulsory settings
	var envs = make(map[string]string)
	for _, env := range envNames {
		v, err := lookupPrefixedEnv(env)
		if err != nil {
			return &appConfig, err
		}
		envs[env] = v
	}

	appConfig.AllowedHosts = []string{envs["SMTP_HOST"]}
	appConfig.BackendConfig = backends.BackendConfig{
		"save_process":      "HeadersParser|Hasher|Debugger|MQTT",
		"validate_process":  "",
		"primary_mail_host": envs["SMTP_HOST"],
		"mqtt_broker":       envs["MQTT_BROKER"],
		"mqtt_clientid":     envs["MQTT_CLIENTID"],
		"mqtt_username":     envs["MQTT_USERNAME"],
		"mqtt_password":     envs["MQTT_PASSWORD"],
		"mqtt_topic":        envs["MQTT_TOPIC"],
		"mqtt_email_token":  envs["EMAIL_TOKEN"],
	}

	for i, _ := range appConfig.Servers {
		appConfig.Servers[i].Hostname = envs["SMTP_HOST"]
	}

	return &appConfig, nil
}
