package main

import (
	"context"
	"fmt"
	"log"
	"net/http"
	"strings"
	"sync"
	"time"

	"git.joco.dk/snr/fermentord/internal/api"
	"git.joco.dk/snr/fermentord/internal/configuration"
	"git.joco.dk/snr/fermentord/pkg/daemon"
	"github.com/getsentry/sentry-go"
	"github.com/gofrs/uuid"
	"github.com/nats-io/nats.go"
	"github.com/prometheus/client_golang/prometheus/promhttp"
)

func main() {
	// Sentry
	err := sentry.Init(sentry.ClientOptions{
		Dsn:              "https://7278625538334140991ce433e0ad292f@sentry.joco.dk/24",
		TracesSampleRate: 0.1,
	})
	if err != nil {
		log.Fatal(err)
	}
	defer sentry.Flush(10 * time.Second)

	// Configuration
	configuration.Initialize()
	config := configuration.LoadConfiguration()

	_, err = uuid.FromString(config.Brew.UUID)
	if err != nil {
		log.Fatalf("Brew ID is not configured: %v", err)
	}

	// NATS
	servers := strings.Join(config.NATS.Servers, ",")
	userInfo := nats.UserInfo(config.NATS.Username, config.NATS.Password)
	nc, err := nats.Connect(servers, userInfo)
	if err != nil {
		log.Fatal(err)
	}

	js, err := nc.JetStream(nats.PublishAsyncMaxPending(4096))
	if err != nil {
		log.Fatal(err)
	}

	// HTTP
	mux := http.NewServeMux()
	srv := &http.Server{
		Addr:    fmt.Sprintf(":%v", config.HTTP.Port),
		Handler: mux,
	}
	api := api.NewAPI(nc)

	// Metrics
	mux.Handle("/metrics", promhttp.Handler())
	mux.HandleFunc("/health", api.HealthCheck)

	// Main
	ctx, shutdown := context.WithCancel(context.Background())
	wg := &sync.WaitGroup{}

	wg.Add(1)
	go mainLoop(ctx, wg, js)

	go srv.ListenAndServe()

	daemon.WaitForSignalsDefault()
	log.Print("Shutting down")

	// Initiate graceful shutdown.
	wg.Add(1)
	go shutdownHTTP(context.Background(), wg, srv)
	shutdown()
	wg.Wait()
	nc.Close()
	log.Print("Shutdown complete")
}
