package serverimp

import (
	"flag"
	"fmt"
	"os"
	"os/signal"
	"syscall"

	"github.com/tech/sendico/pkg/discovery"
	"github.com/tech/sendico/pkg/mlogger"
	lf "github.com/tech/sendico/pkg/mlogger/factory"
	"github.com/tech/sendico/pkg/server"
	"github.com/tech/sendico/pkg/version"
	"go.uber.org/zap"
)

var (
	configFileFlag = flag.String("config.file", "config.yml", "Path to the configuration file.")
	versionFlag    = flag.Bool("version", false, "Show version information.")
	debugFlag      = flag.Bool("debug", false, "Show debug information.")
)

func prepareLogger() mlogger.Logger {
	flag.Parse()

	return lf.NewLogger(*debugFlag)
}

func RunServer(rootLoggerName string, av version.Printer, factory server.ServerFactoryT) {
	logger := prepareLogger().Named(rootLoggerName)
	logger = logger.With(zap.String("instance_id", discovery.InstanceID()))
	defer func() {
		_ = logger.Sync()
	}()

	// Show version information
	if *versionFlag {
		if _, err := fmt.Fprintln(os.Stdout, av.Print()); err != nil {
			logger.Warn("Failed to print version", zap.Error(err))
		}
		return
	}

	// Create server instance
	instance := NewInstance(factory, logger, *configFileFlag, *debugFlag)

	// Interrupt handler
	go func() {
		c := make(chan os.Signal, 1)
		signal.Notify(c, syscall.SIGINT, syscall.SIGTERM)
		sig := <-c
		logger.Info("Received sigint/segterm signal, shutting down", zap.String("signal", sig.String()))
		instance.Shutdown()
	}()

	// Start server
	logger.Info(fmt.Sprintf("Starting %s", av.Program()), zap.String("version", av.Info()))
	logger.Info("Build context", zap.String("context", av.Context()))
	if err := instance.Start(); err != nil {
		logger.Error("Failed to start service", zap.Error(err))
	}
	logger.Info("Server stopped")
}
