package server import ( "fmt" "os" "strconv" "time" "music-server/internal/backend" "music-server/internal/db" "music-server/internal/logging" "net/http" "go.uber.org/zap" ) type Server struct { port int db *db.Database tokenHandler *TokenHandler httpServer *http.Server } var ( host = os.Getenv("DB_HOST") dbPort = os.Getenv("DB_PORT") dbName = os.Getenv("DB_NAME") username = os.Getenv("DB_USERNAME") password = os.Getenv("DB_PASSWORD") musicPath = os.Getenv("MUSIC_PATH") charactersPath = os.Getenv("CHARACTERS_PATH") logLevel = os.Getenv("LOG_LEVEL") logJSON = os.Getenv("LOG_JSON") == "true" ) // NewServerInstance creates a new Server instance with all dependencies initialized. // Use this for dependency injection and proper lifecycle management. func NewServerInstance() *Server { // Initialize logger if logLevel == "" { logLevel = "info" } logging.Init(logLevel, logJSON) logger := logging.GetLogger() port, _ := strconv.Atoi(os.Getenv("PORT")) // Validate required environment variables if host == "" || dbPort == "" || username == "" || password == "" || dbName == "" || musicPath == "" || charactersPath == "" { logging.GetLogger().Fatal("Invalid settings - missing required environment variables") } // Create database instance database, err := db.NewDatabase(host, dbPort, username, password, dbName) if err != nil { logging.GetLogger().Fatal("Failed to initialize database", zap.String("error", err.Error())) } // Run migrations using the new method if err := database.RunMigrations(); err != nil { logging.GetLogger().Fatal("Migration failed", zap.String("error", err.Error())) } // Initialize backend package with database pool backend.InitBackend(database.Pool) // Initialize token handler with database pool tokenHandler := NewTokenHandler(database.Pool) // Create the server instance appServer := &Server{ port: port, db: database, tokenHandler: tokenHandler, } // Create the HTTP server appServer.httpServer = &http.Server{ Addr: fmt.Sprintf(":%d", port), Handler: appServer.RegisterRoutes(), IdleTimeout: time.Minute, ReadTimeout: 10 * time.Second, WriteTimeout: 30 * time.Second, } logger.Info("Starting server", zap.String("host", host), zap.String("dbPort", dbPort), zap.String("username", username), zap.String("dbName", dbName), ) logger.Info("Paths", zap.String("musicPath", musicPath), zap.String("charactersPath", charactersPath), ) return appServer } // HTTPServer returns the underlying http.Server for serving HTTP requests. func (s *Server) HTTPServer() *http.Server { return s.httpServer } // DB returns the database instance for dependency injection. func (s *Server) DB() *db.Database { return s.db } // NewServer creates a new HTTP server (deprecated, use NewServerInstance instead). // This function is kept for backward compatibility. func NewServer() *http.Server { return NewServerInstance().HTTPServer() }