package main import ( "context" "fmt" "os" "os/signal" "syscall" "time" "git.sharkk.net/Sky/Moonshark/core/config" "git.sharkk.net/Sky/Moonshark/core/http" "git.sharkk.net/Sky/Moonshark/core/logger" "git.sharkk.net/Sky/Moonshark/core/routers" "git.sharkk.net/Sky/Moonshark/core/runner" "git.sharkk.net/Sky/Moonshark/core/utils" "git.sharkk.net/Sky/Moonshark/core/watchers" ) // initRouters sets up the Lua and static routers func initRouters(routesDir, staticDir string, log *logger.Logger) (*routers.LuaRouter, *routers.StaticRouter, error) { // Ensure directories exist if err := utils.EnsureDir(routesDir); err != nil { return nil, nil, fmt.Errorf("routes directory doesn't exist, and could not create it: %v", err) } if err := utils.EnsureDir(staticDir); err != nil { return nil, nil, fmt.Errorf("static directory doesn't exist, and could not create it: %v", err) } // Initialize Lua router for dynamic routes luaRouter, err := routers.NewLuaRouter(routesDir) if err != nil { return nil, nil, fmt.Errorf("failed to initialize Lua router: %v", err) } log.Info("Lua router initialized with routes from %s", routesDir) // Initialize static file router staticRouter, err := routers.NewStaticRouterWithLogger(staticDir, log) if err != nil { return nil, nil, fmt.Errorf("failed to initialize static router: %v", err) } log.Info("Static router initialized with files from %s", staticDir) staticRouter.EnableDebugLog() return luaRouter, staticRouter, nil } func main() { // Initialize logger log := logger.New(logger.LevelDebug, true) log.Server("Starting Moonshark server") // Load configuration from config.lua cfg, err := config.Load("config.lua") if err != nil { log.Warning("Failed to load config.lua: %v", err) log.Info("Using default configuration") cfg = config.New() } switch cfg.GetString("log_level", "info") { case "debug": log.SetLevel(logger.LevelDebug) case "warn": log.SetLevel(logger.LevelWarning) case "error": log.SetLevel(logger.LevelError) case "server": log.SetLevel(logger.LevelServer) case "fatal": log.SetLevel(logger.LevelFatal) default: log.SetLevel(logger.LevelInfo) } // Get port from config or use default port := cfg.GetInt("port", 3117) // Initialize routers routesDir := cfg.GetString("routes_dir", "./routes") staticDir := cfg.GetString("static_dir", "./static") luaRouter, staticRouter, err := initRouters(routesDir, staticDir, log) if err != nil { log.Fatal("Router initialization failed: %v", err) } if cfg.GetBool("watchers", true) { // Set up file watchers for automatic reloading luaWatcher, err := watchers.WatchLuaRouter(luaRouter, routesDir, log) if err != nil { log.Warning("Failed to watch routes directory: %v", err) } else { defer luaWatcher.Close() log.Info("File watcher active for Lua routes") } staticWatcher, err := watchers.WatchStaticRouter(staticRouter, staticDir, log) if err != nil { log.Warning("Failed to watch static directory: %v", err) } else { defer staticWatcher.Close() log.Info("File watcher active for static files") } } // Get buffer size from config or use default bufferSize := cfg.GetInt("buffer_size", 20) // Initialize Lua runner runner, err := runner.NewRunner( runner.WithBufferSize(bufferSize), runner.WithLibDirs("./libs"), ) if err != nil { log.Fatal("Failed to initialize Lua runner: %v", err) } log.Server("Lua runner initialized with buffer size %d", bufferSize) defer runner.Close() // Create HTTP server server := http.New(luaRouter, staticRouter, runner, log) // Handle graceful shutdown stop := make(chan os.Signal, 1) signal.Notify(stop, os.Interrupt, syscall.SIGTERM) // Start server in a goroutine go func() { if err := server.ListenAndServe(fmt.Sprintf(":%d", port)); err != nil { if err.Error() != "http: Server closed" { log.Error("Server error: %v", err) } } }() log.Server("Server started on port %d", port) // Wait for interrupt signal <-stop log.Server("Shutdown signal received") // Gracefully shut down the server ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() if err := server.Shutdown(ctx); err != nil { log.Error("Server shutdown error: %v", err) } log.Server("Server stopped") }