package main import ( "context" "embed" "log" "net/http" "os" "os/signal" "syscall" "time" "github.com/gorilla/mux" "beat-harvester/src/config" "beat-harvester/src/handlers" "beat-harvester/src/utils" ) //go:embed src/static/* var staticFS embed.FS func main() { // Initialize configuration cfg := config.Load() // Check dependencies if err := utils.CheckDependencies(); err != nil { log.Fatalf("Missing dependencies: %v", err) } // Setup router r := setupRoutes(cfg) // Create server srv := &http.Server{ Addr: ":" + cfg.Port, Handler: r, } // Start graceful shutdown handler go handleGracefulShutdown(srv) log.Printf("Music Downloader Server starting on port %s", cfg.Port) log.Printf("Default output path: %s", cfg.DefaultOutputPath) log.Printf("Web interface: http://localhost:%s", cfg.Port) if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed { log.Fatalf("Server failed to start: %v", err) } } func setupRoutes(cfg *config.Config) *mux.Router { r := mux.NewRouter() // Initialize handlers with config h := handlers.New(cfg, staticFS) // API routes api := r.PathPrefix("/api").Subrouter() api.HandleFunc("/download", h.Download).Methods("POST") api.HandleFunc("/health", h.Health).Methods("GET") // WebSocket route r.HandleFunc("/ws", h.WebSocket) // Serve static files r.PathPrefix("/").Handler(h.Static()) return r } func handleGracefulShutdown(srv *http.Server) { sigChan := make(chan os.Signal, 1) signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM) <-sigChan log.Println("Shutting down server...") ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() if err := srv.Shutdown(ctx); err != nil { log.Fatalf("Server shutdown failed: %v", err) } log.Println("Server stopped") }