package main

import (
	"context"
	"flag"
	"log"
	"net/http"
	"os"
	"os/signal"
	"syscall"
	"time"

	rc "git.autistici.org/ai3/tools/reports-collector"
	"github.com/prometheus/client_golang/prometheus/promhttp"
)

var (
	addr = flag.String("addr", fromEnv("ADDR", ":4890"), "address to listen on")

	gracefulShutdownTimeout = 5 * time.Second
)

func fromEnv(name, deflt string) string {
	if s := os.Getenv(name); s != "" {
		return s
	}
	return deflt
}

func main() {
	log.SetFlags(0)
	flag.Parse()

	collector := rc.NewCollector(
		new(rc.LogSink),
		new(rc.ReportHandler),
		new(rc.TLSRPTHandler),
		new(rc.LegacyCSPHandler),
		new(rc.DMARCHandler),
	)

	// Create the http.Server.
	mux := http.NewServeMux()
	mux.Handle("/ingest/v1", collector)
	mux.Handle("/metrics", promhttp.Handler())
	server := &http.Server{
		Addr:         *addr,
		Handler:      mux,
		ReadTimeout:  10 * time.Second,
		IdleTimeout:  30 * time.Second,
		WriteTimeout: 10 * time.Second,
	}

	done := make(chan struct{})
	sigCh := make(chan os.Signal, 1)
	go func() {
		<-sigCh
		log.Printf("terminating")
		// Gracefully terminate, then shut down remaining
		// clients.
		ctx, cancel := context.WithTimeout(
			context.Background(), gracefulShutdownTimeout)
		defer cancel()
		if err := server.Shutdown(ctx); err == context.Canceled {
			if err := server.Close(); err != nil {
				log.Printf("error terminating server: %v", err)
			}
		}
		close(done)
	}()

	signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM)

	err := server.ListenAndServe()
	if err != nil && err != http.ErrServerClosed {
		log.Fatalf("server error: %v", err)
	}

	<-done
}