package config import ( "os" "strconv" "strings" "time" ) // Defaults and constants const ( AdminSessionCookieName = "linearvoid_admin_session" MaxAdminUploadBytes int64 = 2 * 1024 * 1024 * 1024 DefaultAdminChunkSize int64 = 8 * 1024 * 1024 MaxAdminChunkSize int64 = 32 * 1024 * 1024 DefaultRateLimitMax = 10 DefaultRateLimitWindow = 10 * time.Second DefaultAdminSessionTTL = 12 * time.Hour DefaultUserSessionTTL = 30 * 24 * time.Hour DefaultChatPort = "3000" ) // PlaylistPath returns the playlist file path from env or default. func PlaylistPath() string { p := strings.TrimSpace(os.Getenv("PLAYLIST_PATH")) if p == "" { return "/app/playlist/playlist.txt" } return p } // MediaDir returns the media directory from env or default. func MediaDir() string { d := strings.TrimSpace(os.Getenv("MEDIA_DIR")) if d == "" { return "/app/media" } return d } // AdminUsername returns the admin username from env or default. func AdminUsername() string { u := strings.TrimSpace(os.Getenv("ADMIN_USERNAME")) if u == "" { return "admin" } return u } // AdminPassword returns the admin password from env or default. func AdminPassword() string { p := strings.TrimSpace(os.Getenv("ADMIN_PASSWORD")) if p == "" { return "admin" } return p } // AdminSessionTTL returns the admin session TTL from env or default. func AdminSessionTTL() time.Duration { raw := strings.TrimSpace(os.Getenv("ADMIN_SESSION_TTL_HOURS")) if raw == "" { return DefaultAdminSessionTTL } hours, err := strconv.Atoi(raw) if err != nil || hours <= 0 { return DefaultAdminSessionTTL } return time.Duration(hours) * time.Hour } // UserSessionTTL returns the user session TTL from env or default (30 days). func UserSessionTTL() time.Duration { raw := strings.TrimSpace(os.Getenv("USER_SESSION_TTL_HOURS")) if raw == "" { return DefaultUserSessionTTL } hours, err := strconv.Atoi(raw) if err != nil || hours <= 0 { return DefaultUserSessionTTL } return time.Duration(hours) * time.Hour } // RateLimitMax returns the chat rate limit max messages per window. func RateLimitMax() int { raw := strings.TrimSpace(os.Getenv("CHAT_RATE_LIMIT_MAX")) if raw == "" { return DefaultRateLimitMax } v, err := strconv.Atoi(raw) if err != nil || v <= 0 { return DefaultRateLimitMax } return v } // RateLimitWindow returns the chat rate limit window duration. func RateLimitWindow() time.Duration { raw := strings.TrimSpace(os.Getenv("CHAT_RATE_LIMIT_WINDOW_S")) if raw == "" { return DefaultRateLimitWindow } v, err := strconv.Atoi(raw) if err != nil || v <= 0 { return DefaultRateLimitWindow } return time.Duration(v) * time.Second } // ChatPort returns the chat service port from env or default. func ChatPort() string { p := strings.TrimSpace(os.Getenv("CHAT_PORT")) if p == "" { return DefaultChatPort } return p } // RedisAddress returns the Redis address from env or default. func RedisAddress() string { a := strings.TrimSpace(os.Getenv("REDIS_URL")) if a == "" { return "redis:6379" } return a } // DatabaseURL returns the database URL from env (empty = SQLite default). func DatabaseURL() string { return strings.TrimSpace(os.Getenv("DATABASE_URL")) }