package main

import (
	"context"
	"errors"
	"fmt"
	"io"
	"net/http"
	"os"
	"os/signal"
	"syscall"
	"time"

	"banger/internal/buildinfo"
	sdkvsock "github.com/firecracker-microvm/firecracker-go-sdk/vsock"
	"github.com/sirupsen/logrus"

	"banger/internal/vsockagent"
)

var _, _, _ = buildinfo.Version, buildinfo.Commit, buildinfo.BuiltAt

func main() {
	ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
	defer cancel()

	logger := logrus.New()
	logger.SetOutput(io.Discard)
	listener, err := sdkvsock.Listener(ctx, logrus.NewEntry(logger), vsockagent.Port)
	if err != nil {
		fmt.Fprintf(os.Stderr, "banger-vsock-agent: %v\n", err)
		os.Exit(1)
	}
	defer listener.Close()

	server := &http.Server{
		Handler:           vsockagent.NewHandler(),
		ReadHeaderTimeout: 3 * time.Second,
	}

	errCh := make(chan error, 1)
	go func() {
		errCh <- server.Serve(listener)
	}()

	select {
	case <-ctx.Done():
		shutdownCtx, shutdownCancel := context.WithTimeout(context.Background(), 5*time.Second)
		defer shutdownCancel()
		_ = server.Shutdown(shutdownCtx)
		if err := <-errCh; err != nil && !errors.Is(err, http.ErrServerClosed) {
			fmt.Fprintf(os.Stderr, "banger-vsock-agent: %v\n", err)
			os.Exit(1)
		}
	case err := <-errCh:
		if err != nil && !errors.Is(err, http.ErrServerClosed) {
			fmt.Fprintf(os.Stderr, "banger-vsock-agent: %v\n", err)
			os.Exit(1)
		}
	}
}
