package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"log"
	"os"
	"os/signal"
	"syscall"
)

const (
	ConfigFile = "world_config.json"
	Version    = "0.1.0"
)

// printHeader displays the EQ2Emu banner and copyright info
func printHeader() {
	fmt.Println("EQ2Emulator World Server")
	fmt.Printf("Version: %s\n", Version)
	fmt.Println()
	fmt.Println("Copyright (C) 2007-2026 EQ2Emulator Development Team")
	fmt.Println("https://www.eq2emu.com")
	fmt.Println()
	fmt.Println("EQ2Emulator is free software licensed under the GNU GPL v3")
	fmt.Println("See LICENSE file for details")
	fmt.Println()
}

// loadConfig loads configuration from JSON file with command line overrides
func loadConfig() (*WorldConfig, error) {
	// Default configuration
	config := &WorldConfig{
		ListenAddr:   "0.0.0.0",
		ListenPort:   9000,
		MaxClients:   1000,
		BufferSize:   8192,
		WebAddr:      "0.0.0.0",
		WebPort:      8080,
		DatabasePath: "world.db",
		XPRate:       1.0,
		TSXPRate:     1.0,
		VitalityRate: 1.0,
		LogLevel:     "info",
		ThreadedLoad: true,
	}

	// Load from config file if it exists
	if data, err := os.ReadFile(ConfigFile); err == nil {
		if err := json.Unmarshal(data, config); err != nil {
			return nil, fmt.Errorf("failed to parse config file: %w", err)
		}
		log.Printf("Loaded configuration from %s", ConfigFile)
	} else {
		log.Printf("Config file %s not found, using defaults", ConfigFile)
	}

	// Command line overrides
	flag.StringVar(&config.ListenAddr, "listen-addr", config.ListenAddr, "UDP listen address")
	flag.IntVar(&config.ListenPort, "listen-port", config.ListenPort, "UDP listen port")
	flag.IntVar(&config.MaxClients, "max-clients", config.MaxClients, "Maximum client connections")
	flag.StringVar(&config.WebAddr, "web-addr", config.WebAddr, "Web server address")
	flag.IntVar(&config.WebPort, "web-port", config.WebPort, "Web server port")
	flag.StringVar(&config.DatabasePath, "db-path", config.DatabasePath, "Database file path")
	flag.StringVar(&config.LogLevel, "log-level", config.LogLevel, "Log level (debug, info, warn, error)")
	flag.BoolVar(&config.ThreadedLoad, "threaded-load", config.ThreadedLoad, "Use threaded loading")
	flag.Parse()

	return config, nil
}

// saveConfig saves the current configuration to file
func saveConfig(config *WorldConfig) error {
	data, err := json.MarshalIndent(config, "", "	")
	if err != nil {
		return fmt.Errorf("failed to marshal config: %w", err)
	}

	if err := os.WriteFile(ConfigFile, data, 0644); err != nil {
		return fmt.Errorf("failed to write config file: %w", err)
	}

	return nil
}

// setupSignalHandlers sets up graceful shutdown on SIGINT/SIGTERM
func setupSignalHandlers(world *World) <-chan os.Signal {
	sigChan := make(chan os.Signal, 1)
	signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)

	go func() {
		sig := <-sigChan
		log.Printf("Received signal %v, initiating graceful shutdown...", sig)
		world.Shutdown()
	}()

	return sigChan
}

func main() {
	printHeader()

	// Load configuration
	config, err := loadConfig()
	if err != nil {
		log.Fatalf("Configuration error: %v", err)
	}

	// Save config file with any command line overrides
	if err := saveConfig(config); err != nil {
		log.Printf("Warning: failed to save config: %v", err)
	}

	// Create world server instance
	world, err := NewWorld(config)
	if err != nil {
		log.Fatalf("Failed to create world server: %v", err)
	}

	// Initialize all components
	log.Println("Initializing EQ2Emulator World Server...")
	if err := world.Initialize(); err != nil {
		log.Fatalf("Failed to initialize world server: %v", err)
	}

	// Setup signal handlers for graceful shutdown
	setupSignalHandlers(world)

	// Run the server
	log.Println("Starting World Server...")
	if err := world.Run(); err != nil {
		log.Fatalf("World server error: %v", err)
	}

	log.Println("World Server stopped gracefully")
}
