package main

import (
	"context"
	"flag"
	"log/slog"
	"os"
	"os/signal"
	"syscall"
	"time"

	"yobble-gateway-go/internal/config"
	"yobble-gateway-go/internal/logger"
	"yobble-gateway-go/internal/server"
	"yobble-gateway-go/pkg/geoip"
)

func main() {
	var configPath string
	flag.StringVar(&configPath, "config", "configs/config.yml", "config file path")
	flag.Parse()

	if configPath == "" {
		configPath = os.Getenv("CONFIG_PATH")
	}

	logger.InitLogger("info", "text")

	op := "main.main"
	log := logger.NewLoggerWithOp(op)

	cfg, err := config.Load(configPath)
	if err != nil {
		log.Error("failed to load configuration", slog.String("path", configPath), slog.Any("error", err))
		os.Exit(1)
	}

	// Повторно инициализируем логгер с настройками из конфигурации
	logger.InitLogger(cfg.Logging.Level, cfg.Logging.Format)
	log = logger.NewLoggerWithOp(op) // Повторно создаем логгер с обновленным уровнем и форматом

	log.Info("configuration loaded successfully")

	// Инициализируем сервис GeoIP
	geoipService, err := geoip.NewGeoIPService(cfg.Gateway.GeoIPDB, cfg.Gateway.BlockedCountries)
	if err != nil {
		log.Error("failed to initialize GeoIP service", slog.Any("error", err))
		os.Exit(1)
	}
	defer geoipService.Close()

	// Создаем экземпляр сервера
	srv := server.NewServer(cfg, geoipService)

	// Запускаем сервер в отдельной горутине
	done := make(chan struct{})
	errChan := srv.Start(cfg.TLS.FullChain, cfg.TLS.PrivateKey)

	// Настраиваем перехват системных сигналов для graceful shutdown
	sigChan := make(chan os.Signal, 1)
	signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)

	go func() {
		select {
		case err := <-errChan:
			if err != nil {
				log.Error("server error", slog.Any("error", err))
			}
		case sig := <-sigChan:
			log.Info("received signal", slog.String("signal", sig.String()))
			// Создаем контекст с таймаутом для graceful shutdown
			shutdownCtx, cancel := context.WithTimeout(context.Background(), 35*time.Second) // TODO: Make configurable
			defer cancel()

			if err := srv.Shutdown(shutdownCtx); err != nil {
				log.Error("server graceful shutdown failed", slog.Any("error", err))
				os.Exit(1)
			}
		}
		close(done)
	}()

	<-done
	log.Info("application stopped")
}
