package main

import (
	"context"
	"fmt"
	"os"
	"os/signal"
	"syscall"
	"time"

	"goshs.de/goshs/v2/config"
	"goshs.de/goshs/v2/goshsversion"
	"goshs.de/goshs/v2/logger"
	"goshs.de/goshs/v2/options"
	"goshs.de/goshs/v2/sanity"
	"goshs.de/goshs/v2/server"
)

func main() {
	var err error

	// flags
	opts, print := options.Parse()

	// Print config
	if print {
		config, err := config.PrintExample()
		if err != nil {
			panic(err)
		}
		fmt.Println(config)
		os.Exit(0)
	}

	// Load config
	if opts.ConfigFile != "" {
		opts, err = config.LoadConfig(opts)
		if err != nil {
			logger.Fatalf("Failed to load config: %+v", err)
		}
	}

	// Ensure ~/.config/goshs exists
	if _, err = config.Dir(); err != nil {
		logger.Warnf("Could not create config directory: %+v", err)
	}

	// Sanitize webroot and check sanity
	opts, err = sanity.Sanitize(opts)
	if err != nil {
		logger.Fatalf("Failed to sanitize webroot: %+v", err)
	}

	opts, err = sanity.Check(opts)
	if err != nil {
		logger.Fatalf("Sanity check failed: %+v", err)
	}

	// Further processing of options
	opts, err = sanity.FurtherProcessing(opts)
	if err != nil {
		logger.Fatalf("Further processing failed: %+v", err)
	}

	logger.PrintBanner(goshsversion.GoshsVersion)

	// Start all servers
	shutdown := server.StartAll(opts)

	done := make(chan os.Signal, 1)
	signal.Notify(done, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
	<-done
	logger.Infof("Received CTRL+C, shutting down gracefully...")

	ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
	defer cancel()
	shutdown(ctx)
	logger.Infof("Shutdown complete")
}
