package main

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

	"a301_game_server/config"
	"a301_game_server/internal/db"
	"a301_game_server/internal/game"
	"a301_game_server/internal/network"
	"a301_game_server/pkg/logger"
)

func main() {
	configPath := flag.String("config", "config/config.yaml", "path to configuration file")
	flag.Parse()

	cfg, err := config.Load(*configPath)
	if err != nil {
		panic("failed to load config: " + err.Error())
	}

	if err := logger.Init(cfg.Log.Level); err != nil {
		panic("failed to init logger: " + err.Error())
	}
	defer logger.Sync()

	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()

	// Connect to PostgreSQL.
	dbPool, err := db.NewPool(ctx, &cfg.Database)
	if err != nil {
		logger.Fatal("failed to connect to database", "error", err)
	}
	defer dbPool.Close()

	// Run migrations.
	if err := dbPool.RunMigrations(ctx); err != nil {
		logger.Fatal("failed to run migrations", "error", err)
	}

	// Create game server.
	gs := game.NewGameServer(cfg, dbPool)
	gs.Start()
	defer gs.Stop()

	// Create and start network server.
	srv := network.NewServer(cfg, gs)

	// Graceful shutdown on SIGINT/SIGTERM.
	sigCh := make(chan os.Signal, 1)
	signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM)

	go func() {
		sig := <-sigCh
		logger.Info("received signal, shutting down", "signal", sig)
		cancel()
	}()

	logger.Info("game server starting",
		"address", cfg.Server.Address(),
		"tickRate", cfg.World.TickRate,
		"aoiEnabled", cfg.World.AOI.Enabled,
	)

	if err := srv.Start(ctx); err != nil {
		logger.Fatal("server error", "error", err)
	}

	logger.Info("server shutdown complete")
}
