package syslog

import (
	"fmt"
	"log"
	"time"

	"git.openpdu.org/OpenPDU/openpdu/events"
	"github.com/RackSec/srslog"
	"github.com/spf13/viper"
)

var logger *srslog.Writer
var Connected bool

var defaults = map[string]interface{}{
	"Syslog.Host":     "localhost",
	"Syslog.Port":     514,
	"Syslog.Protocol": "udp",
}

func init() {
	for k, v := range defaults {
		viper.SetDefault(k, v)
	}
	Connected = false
	events.AddListener("config_changed", Reconfigure)
	go Connect()
}

func Reconfigure() {
	if logger != nil {
		logger.Close()
	}

	Notice("Syslog disconnected")
	events.FireEvent("syslog_disconnected")
	Connected = false

	go Connect()
}

func Connect() {
	var err error

	hostname := viper.GetString("Syslog.Host")
	port := viper.GetInt("Syslog.Port")
	protocol := viper.GetString("Syslog.Protocol")
	conn := fmt.Sprintf("%s:%d", hostname, port)
	logger, err = srslog.Dial(protocol, conn, srslog.LOG_WARNING|srslog.LOG_DAEMON, "openpdu")

	if err != nil {
		Err(fmt.Sprintf("failed to connect to syslog: %s", err.Error()))
		time.Sleep(1 * time.Second)
		go Connect()
	}

	Connected = true
}

func Alert(msg string) {
	if logger == nil {
		log.Print(msg)
	} else {
		logger.Alert(msg)
	}
}

func Crit(msg string) {
	if logger == nil {
		log.Print(msg)
	} else {
		logger.Crit(msg)
	}
}

func Err(msg string) {
	if logger == nil {
		log.Print(msg)
	} else {
		logger.Err(msg)
	}
}

func Warning(msg string) {
	if logger == nil {
		log.Print(msg)
	} else {
		logger.Warning(msg)
	}
}

func Notice(msg string) {
	if logger == nil {
		log.Print(msg)
	} else {
		logger.Notice(msg)
	}
}

func Info(msg string) {
	if logger == nil {
		log.Print(msg)
	} else {
		logger.Info(msg)
	}
}

func Debug(msg string) {
	if logger == nil {
		log.Print(msg)
	} else {
		logger.Debug(msg)
	}
}
