package main

import (
	"flag"
	"gopkg.in/mcuadros/go-syslog.v2"
	"io"
	"log"
	"os"
	"time"
)

type logServer struct {
	channel  syslog.LogPartsChannel
	handler  syslog.Handler
	msgCount int64
	config   *config
}

type config struct {
	debug          bool
	host           string
	stats          bool
	statsOnStdErr  bool
	updateInterval time.Duration
}

func main() {

	conf := &config{}
	flag.StringVar(&conf.host, "host", "0.0.0.0:5144", "Address for TCP socket listener as host:port")
	flag.BoolVar(&conf.debug, "debug", false, "Enable debugging")
	flag.BoolVar(&conf.stats, "stats", false, "Enable interval statistics")
	flag.BoolVar(&conf.statsOnStdErr, "statsOnStdErr", false, "Send stats to stderr instead of stdout")
	flag.DurationVar(&conf.updateInterval, "updateInterval", 5*time.Second, "Number of seconds between stat updates, if enabled")

	flag.Parse()

	l := &logServer{
		config: conf,
	}
	l.channel = make(syslog.LogPartsChannel)
	l.handler = syslog.NewChannelHandler(l.channel)

	server := syslog.NewServer()
	server.SetFormat(syslog.RFC5424)
	server.SetHandler(l.handler)
	server.ListenTCP(l.config.host)
	server.Boot()

	if l.config.stats {
		go func(l *logServer) {
			var delta, current, previous int64
			var output io.Writer = os.Stdout
			if l.config.statsOnStdErr {
				output = os.Stderr
			}
			slogger := log.New(output, "", log.Ldate|log.Ltime|log.Lmicroseconds)
			for {
				previous = current
				<-time.After(l.config.updateInterval)
				current = l.msgCount
				delta = current - previous
				slogger.Printf("processed %d msgs since last interval, avg. %04.2f msgs/sec\n", delta,
					float64(delta)/l.config.updateInterval.Seconds())
			}
		}(l)
	}

	go func(l *logServer) {
		for msg := range l.channel {
			if l.config.debug {
				log.Printf("%v", msg)
			}
			l.msgCount++
		}
	}(l)

	server.Wait()
}