/**
 * ARCHITECTURE DOCUMENTATION: HttpServer - Web Server and Real-Time Notification Hub
 * ===================================================================================
 *
 * HttpServer provides the HTTP/HTTPS server for Minecraft Creator Tools and serves as
 * a central hub for real-time client notifications via WebSocket connections. It exposes
 * REST APIs for server management and proxies events from DedicatedServer instances.
 *
 * ## Core Responsibilities
 *
 * 1. **HTTP Server**: Serves static files, API endpoints, and the web application
 * 2. **WebSocket Notifications**: Broadcasts real-time events to connected clients
 * 3. **Storage Watching**: Monitors NodeStorage for file changes and broadcasts updates
 * 4. **Authentication**: Manages session tokens and permission levels
 * 5. **MCP Server Integration**: Hosts Model Context Protocol server
 * 6. **Server Management API**: REST endpoints for controlling DedicatedServer instances
 *
 * ## API Architecture
 *
 * The HTTP server exposes REST endpoints for remote server management:
 *
 * ```
 * /api/auth              - Authentication with passcode
 * /api/<slot>/start      - Start a DedicatedServer on the specified slot
 * /api/<slot>/stop       - Stop the server on the specified slot
 * /api/<slot>/status     - Get server status and recent log messages
 * /api/<slot>/command    - Send a slash command to the server
 * /api/<slot>/deploy     - Deploy add-on content to the server
 * /api/content/<path>    - Access files when in view/edit mode
 * /api/validate          - Validate Minecraft content
 * /api/shutdown          - Graceful shutdown (view mode only)
 * /api/acceptEula        - Accept Minecraft EULA (admin only, enables BDS features)
 * /api/eulaStatus        - Check if EULA has been accepted
 * /api/commands          - List available ToolCommands
 * /api/commands/<cmd>    - Execute a ToolCommand (POST with args/flags JSON body)
 * ```
 *
 * ## Real-Time Sync Architecture
 *
 * HttpServer sits between server-side file changes and client-side updates:
 *
 * ```
 * NodeStorage (fs.watch)  ──→  HttpServer  ──→  WebSocket  ──→  HttpStorage (client)
 *      │                           │                                   │
 *      └── IStorageChangeEvent ────┘                                   │
 *                                  │                                   │
 *                   IServerNotification ─────────────────→  onFileUpdated event
 *                                                                      │
 *                                                               MCWorld ─→ WorldView
 * ```
 *
 * ## WebSocket Event Types
 *
 * The WebSocket connection broadcasts various event types to clients:
 *
 * | Event Name         | Description                                     |
 * |--------------------|-------------------------------------------------|
 * | statusUpdate       | Server status changed (starting, started, etc.)|
 * | playerJoined       | Player connected to the Minecraft server        |
 * | playerLeft         | Player disconnected from the server             |
 * | playerMoved        | Player position changed (from position polling) |
 * | storage/change     | File in watched storage was modified            |
 * | debugConnected     | Script debugger connection established          |
 * | debugStats         | Profiling statistics from script debugger       |
 * | gameEvent          | Generic game event from server                  |
 * | serverShutdown     | MCT server is shutting down (sent before close) |
 *
 * ## Storage Watcher Integration
 *
 * The server maintains watchers for NodeStorage instances and converts storage events
 * to WebSocket notifications:
 *
 * - **startWatchingStorage()**: Registers a storage for watching with a unique slot ID
 * - **stopWatchingStorage()**: Stops watching a specific storage
 * - **stopAllStorageWatchers()**: Cleanup when server stops
 * - **_handleStorageChange()**: Converts IStorageChangeEvent to IServerNotification
 *
 * ## Authentication & Permission Levels
 *
 * Four permission levels control access to different features:
 *
 * | Level              | Access                                          |
 * |--------------------|-------------------------------------------------|
 * | displayReadOnly    | View server status and logs                     |
 * | fullReadOnly       | Above + file browsing                           |
 * | updateState        | Above + start/stop servers, deploy content      |
 * | admin              | Full access including shutdown                  |
 *
 * Passcodes are set via command line and validated using encrypted tokens.
 *
 * ## SSL/TLS Support (Experimental)
 *
 * HttpServer supports experimental HTTPS via command-line configuration:
 * - Certificate and key files specified at startup
 * - Not persisted to disk for security
 * - Optional HTTPS-only mode
 *
 * ## Integration with ServerManager
 *
 * HttpServer receives events from ServerManager and converts them to notifications:
 *
 * ```
 * DedicatedServer ──► ServerManager ──► HttpServer ──► WebSocket Clients
 *       │                  │                │
 *       │                  │ bubbleServerStarted
 *       │                  │     │
 *       │                  │     └─► notify({ eventName: 'statusUpdate', ... })
 *       │                  │
 *       │                  │ bubblePlayerConnected
 *       │                  │     │
 *       │                  │     └─► notify({ eventName: 'playerJoined', ... })
 * ```
 *
 * ## Related Files
 *
 * - ServerManager.ts: Creates HttpServer and forwards server events
 * - IServerNotification.ts: Notification message types
 * - NodeStorage.ts: Server-side file watching with fs.watch()
 * - HttpStorage.ts: Client-side notification receiver
 * - IStorageWatcher.ts: Interface definitions for watcher system
 * - MinecraftMcpServer.ts: MCP server for AI tool integration
 *
 * ## Key Methods
 *
 * - init(): Initialize HTTP/HTTPS server and WebSocket
 * - stop(): Cleanup resources including storage watchers
 * - notify(): Broadcast notification to all connected WebSocket clients
 * - notifyStatusUpdate(): Send server status change to a specific slot
 * - sendNotificationToSlot(): Send notification to clients subscribed to a slot
 * - startWatchingStorage(): Begin monitoring a NodeStorage instance
 * - processRequest(): Main HTTP request handler and router
 */
import * as http from "http";
import ServerManager from "./ServerManager";
import LocalEnvironment from "./LocalEnvironment";
import NodeStorage from "./NodeStorage";
import { ServerPermissionLevel } from "./IAuthenticationToken";
import CreatorTools from "../app/CreatorTools";
import { ISlotConfig } from "../app/CreatorToolsAuthentication";
import { DedicatedServerStatus, OutputLine } from "./DedicatedServer";
import IStorage from "../storage/IStorage";
import ISslConfig from "./ISslConfig";
import { IServerNotification, IServerNotificationBody } from "./IServerNotification";
export interface CartoServerAuthenticationResponse {
    token?: string;
    iv?: string;
    authTag?: string;
    permissionLevel: ServerPermissionLevel;
    serverStatus: CartoServerStatusResponse[];
    /** Whether the Minecraft EULA has been accepted (required for BDS features) */
    eulaAccepted?: boolean;
}
export interface CartoServerStatusResponse {
    id: number;
    status?: DedicatedServerStatus;
    time: number;
    /** Recent log messages from the server */
    recentMessages?: OutputLine[];
    /** Slot configuration - included in initial auth response */
    slotConfig?: ISlotConfig;
    /** World ID currently associated with this slot */
    worldId?: string;
}
export default class HttpServer {
    host: string;
    port: number;
    creatorTools: CreatorTools | undefined;
    headers: {
        "Access-Control-Allow-Origin": string;
        "Access-Control-Allow-Methods": string;
        "Access-Control-Max-Age": number;
        "Access-Control-Allow-Headers": string;
        "Access-Control-Allow-Credentials": string;
    };
    private _webStorage;
    private _resStorage;
    private _dataStorage;
    private _distStorage;
    private _schemasStorage;
    private _formsStorage;
    private _esbuildWasmStorage;
    private _serverManager;
    private _localEnvironment;
    private _algorithm;
    private _httpsServer;
    private _httpServer;
    private _mcpServer;
    private _pwdHash;
    private _isListeningMetaFlag;
    private _readyResolvers;
    /**
     * Returns true if the HTTP server is actually listening and accepting connections.
     * This checks the underlying server state, not just the flag.
     */
    get isListening(): boolean;
    /**
     * Returns a promise that resolves when the server is ready to accept connections.
     * If the server is already listening, resolves immediately.
     * @param timeoutMs Optional timeout in milliseconds. If provided and the server
     *   doesn't become ready in time, the promise rejects with a timeout error.
     */
    waitForReady(timeoutMs?: number): Promise<void>;
    /**
     * Called when the server starts listening to mark it as ready and resolve any pending waiters.
     */
    private _markAsListening;
    private _sslConfig?;
    get sslConfig(): ISslConfig | undefined;
    set sslConfig(config: ISslConfig | undefined);
    private _tempContent;
    private _contentStorage;
    private _contentPath;
    private _isViewMode;
    private _isEditMode;
    private _mcpRequireAuth;
    private _mcpServerInitPromise;
    private _wsServer;
    private _wsClients;
    private _storageWatchers;
    private _slotStorages;
    private static readonly BLOCKED_FILE_NAMES;
    private static readonly SAFE_EXTENSIONS;
    /** Whether local res/ storage includes the vanilla serve folder with PNG textures */
    private _hasLocalVanillaServe;
    constructor(localEnv: LocalEnvironment, serverManager: ServerManager);
    init(): void;
    /**
     * Initialize HTTPS server with experimental SSL configuration.
     * SSL config is passed via command line arguments - nothing is persisted.
     */
    private initHttps;
    /**
     * Build HTTPS server options from experimental SSL configuration.
     */
    private buildHttpsOptions;
    /**
     * Initialize WebSocket server for pushing notifications to clients.
     * The WebSocket server shares the HTTP server and handles upgrade requests to /ws/notifications.
     */
    private initWebSocketServer;
    /**
     * Authenticate a WebSocket upgrade request.
     * Returns the permission level if authenticated, undefined otherwise.
     *
     * Requires a valid auth token via query string (?token=...) or mctauth cookie.
     * Localhost connections are NOT exempted — all WebSocket clients must authenticate.
     */
    private authenticateWebSocketRequest;
    /**
     * Handle a new WebSocket connection.
     */
    private handleWebSocketConnection;
    /**
     * Handle incoming WebSocket message (subscription requests).
     */
    private handleWebSocketMessage;
    /**
     * Validate an encrypted auth token and return the permission level.
     */
    private validateToken;
    /**
     * Broadcast a notification to all subscribed WebSocket clients.
     * @param notification The notification to broadcast
     */
    broadcastNotification(notification: IServerNotification): void;
    /**
     * Create and broadcast a notification.
     * Helper method for common notification patterns.
     */
    notify(body: IServerNotificationBody): void;
    /**
     * Notify clients of a file change in world content.
     */
    notifyFileChange(eventName: "fileChanged" | "fileAdded" | "fileRemoved", slot: number, category: "behavior_packs" | "resource_packs" | "world", path: string): void;
    /**
     * Notify clients of a server state change.
     */
    notifyServerState(slot: number, state: "starting" | "started" | "stopping" | "stopped" | "error", message?: string): void;
    /**
     * Notify clients of a player movement.
     */
    notifyPlayerMoved(slot: number, playerName: string, position: {
        x: number;
        y: number;
        z: number;
    }, rotation?: {
        yaw: number;
        pitch: number;
    }, dimension?: string): void;
    /**
     * Forward a game event from Minecraft to WebSocket clients.
     */
    notifyGameEvent(slot: number, minecraftEventName: string, data: object): void;
    /**
     * Notify clients of a full status update for a server slot.
     * This replaces the need for polling /api/{slot}/status/
     *
     * @param slot The server slot number
     * @param status The current DedicatedServerStatus value
     * @param recentMessages Recent messages from the server
     * @param title Optional server title
     */
    notifyStatusUpdate(slot: number, status: number, recentMessages?: Array<{
        message: string;
        received: number;
        type?: number;
    }>, title?: string): void;
    /**
     * Start watching a NodeStorage for file changes and broadcast them via WebSocket.
     * This enables real-time synchronization of file changes to connected clients.
     *
     * @param storage The NodeStorage to watch
     * @param slot The server slot number this storage is associated with
     * @param category The category of content (behavior_packs, resource_packs, world)
     */
    startWatchingStorage(storage: NodeStorage, slot: number, category: "behavior_packs" | "resource_packs" | "world"): void;
    /**
     * Stop watching a specific storage.
     */
    stopWatchingStorage(storage: NodeStorage): void;
    /**
     * Stop watching all storages.
     */
    stopAllStorageWatchers(): void;
    /**
     * Handle a storage change event and broadcast it to WebSocket clients.
     */
    private _handleStorageChange;
    stop(reason?: string): Promise<void>;
    private _salt;
    getPasswordHash(): Buffer<ArrayBufferLike>;
    getSalt(): Buffer<ArrayBufferLike>;
    /**
     * Generates a generic fingerprint hash for token binding.
     * Uses partial IP and browser family to balance security with usability.
     *
     * Note: This is intentionally "soft" binding - we only use partial IP
     * to avoid breaking sessions for mobile users while still providing
     * some protection against token theft across different networks.
     */
    generateFingerprint(userAgent?: string, ipAddress?: string): string;
    /**
     * Validates that a token fingerprint matches current request.
     * Uses timing-safe comparison to prevent timing attacks.
     */
    validateFingerprint(storedFingerprint: string, currentFingerprint: string): boolean;
    /**
     * Gets the expected session ID for a given permission level.
     * Used to validate that tokens were issued for the current server session.
     * This prevents replay attacks with tokens from previous server restarts.
     */
    getExpectedSessionIdForPermission(permissionLevel: ServerPermissionLevel): string | undefined;
    getAllowedCorsOrigins(): string[];
    /**
     * Check if an origin is allowed for CORS.
     * Allows any localhost/127.0.0.1 port for development convenience.
     */
    isOriginAllowed(origin: string | undefined): boolean;
    getCorsHeaders(req: http.IncomingMessage): {
        [key: string]: string;
    };
    /**
     * Register temporary content to be served at a specific path.
     * Useful for serving project-specific content for headless rendering.
     * @param urlPath The URL path to serve (e.g., "/temp/geometry.json")
     * @param content The content to serve (string for JSON/text, Uint8Array for binary)
     * @param contentType The content type (e.g., "application/json", "image/png")
     */
    registerTempContent(urlPath: string, content: string | Uint8Array, contentType: string): void;
    /**
     * Unregister temporary content.
     * @param urlPath The URL path to remove
     */
    unregisterTempContent(urlPath: string): void;
    /**
     * Clear all temporary content.
     */
    clearTempContent(): void;
    /**
     * Set the content path for serving local files via /api/content.
     * Used by the 'view' command to serve Minecraft content for browsing.
     * @param contentPath Absolute path to the local folder to serve
     */
    setContentPath(contentPath: string): void;
    /**
     * Get the content path if set.
     */
    getContentPath(): string | undefined;
    /**
     * Set whether the server is running in "view" mode.
     * When true, enables the /api/shutdown endpoint for graceful shutdown.
     */
    setViewMode(isViewMode: boolean): void;
    /**
     * Check if the server is running in view mode.
     */
    isViewMode(): boolean;
    /**
     * Set whether the server is running in "edit" mode.
     * When true, enables write operations (PUT/DELETE) on /api/content endpoints.
     * Edit mode also enables view mode features like /api/shutdown.
     */
    setEditMode(isEditMode: boolean): void;
    /**
     * Check if the server is running in edit mode.
     */
    isEditMode(): boolean;
    /**
     * Set whether MCP requires authentication even from localhost.
     * When false (default), localhost requests to /mcp bypass authentication.
     * When true, all /mcp requests must authenticate via passcode or session token.
     */
    setMcpRequireAuth(requireAuth: boolean): void;
    /**
     * Handles an MCP request by lazily initializing the MCP server and delegating.
     * Sets CORS headers before handing off to the MCP transport, which manages
     * its own response headers (the SDK's StreamableHTTPServerTransport).
     */
    private _handleMcpRequest;
    /**
     * Check if a file name is safe to serve (not in blocked list and has safe extension).
     */
    private isFileSafeToServe;
    /**
     * Check if a folder name is safe to traverse (not hidden or blocked).
     */
    private isFolderSafeToServe;
    getRootPath(): string;
    /**
     * Get the path to the res/ folder, checking both the default location
     * and the public/ folder for development environments.
     *
     * The serve vanilla folder (with PNG-converted textures) is often only
     * available under public/res/ — not under toolbuild/jsn/res/. This method
     * checks multiple candidate paths to find the one that actually contains
     * vanilla resource data.
     */
    getResRootPath(): string;
    /**
     * Check if a URL path is for vanilla resources (under /res/latest/van/)
     */
    isVanillaResourcePath(urlPath: string): boolean;
    parseCookies(req: http.IncomingMessage): {
        [name: string]: string;
    };
    processRequest(req: http.IncomingMessage, res: http.ServerResponse): void;
    getStatus(portOrSlot: number, includeConfig?: boolean): CartoServerStatusResponse;
    /**
     * Handle requests to /api/content/* for serving local Minecraft content.
     * Generates synthetic index.json files for folders and serves safe file types.
     * In edit mode, also handles PUT (create/update), DELETE, and POST (mkdir) operations.
     */
    private handleContentRequest;
    /**
     * Generate and serve a synthetic index.json for a folder.
     */
    private serveContentFolderListing;
    /**
     * Serve a file from the content storage.
     */
    private serveContentFile;
    /**
     * Handle requests to /api/worldContent/{slot}/* for serving dedicated server world content.
     * This endpoint exposes a virtualized view of the server's content folders:
     * - /api/worldContent/{slot}/behavior_packs/ -> development_behavior_packs
     * - /api/worldContent/{slot}/resource_packs/ -> development_resource_packs
     * - /api/worldContent/{slot}/world/ -> worlds/defaultWorld
     *
     * The slot parameter is the port number of the dedicated server.
     */
    private handleWorldContentRequest;
    /**
     * Serve the root listing of world content categories.
     */
    private serveWorldContentRootListing;
    /**
     * Serve a folder listing for world content.
     */
    private serveWorldContentFolderListing;
    /**
     * Serve a file from world content.
     */
    private serveWorldContentFile;
    /**
     * Handle PUT requests to /api/content/* for creating or updating files.
     * Requires edit mode and updateState permission.
     */
    private handleContentPut;
    /**
     * Handle DELETE requests to /api/content/* for deleting files.
     * Requires edit mode and updateState permission.
     */
    private handleContentDelete;
    /**
     * Handle POST requests to /api/content/* for creating directories or other actions.
     * Requires edit mode and updateState permission.
     */
    private handleContentPost;
    /**
     * Read the full request body as a Buffer.
     */
    private readRequestBody;
    sendErrorRequest(statusCode: number, message: string, req: http.IncomingMessage, res: http.ServerResponse): void;
    hasPermissionLevel(currentPermLevel: ServerPermissionLevel, requiredPermissionLevel: ServerPermissionLevel, req: http.IncomingMessage, res: http.ServerResponse): boolean;
    serveContent(baseSegment: string, relativeUrl: string, storage: IStorage, res: http.ServerResponse): Promise<void>;
    encrypt(text: string): {
        iv: string;
        content: string;
        authTag: string;
    };
    decrypt(iv: string, content: string, authTag?: string): string;
    getMimeTypeForFile(extension: string): "application/json" | "application/zip" | "image/jpeg" | "image/png" | "image/svg+xml" | "image/x-icon" | "text/css" | "text/javascript" | "font/woff" | "font/woff2" | "font/ttf";
    /**
     * Escapes a string for safe inclusion in HTML/JavaScript.
     * Prevents XSS attacks from user-controlled content.
     */
    private escapeForHtml;
    /**
     * Escapes a string for safe inclusion in a JavaScript string literal.
     */
    private escapeForJs;
    /**
     * Handle upload requests with lazy server initialization.
     * This allows edit/view modes to deploy content to BDS without requiring
     * the server to be pre-configured on startup.
     *
     * The server will be lazily initialized when the first deploy is attempted.
     */
    private handleUploadWithLazyInit;
    /**
     * Handle POST /api/{slot}/stop - Stop the server on a specific slot.
     */
    private handleSlotStop;
    /**
     * Handle POST /api/{slot}/restart - Restart the server on a specific slot.
     */
    private handleSlotRestart;
    /**
     * Handle requests to /api/worlds/* endpoints.
     * Provides CRUD operations for managed worlds and their backups.
     *
     * Endpoints:
     * GET  /api/worlds - List all managed worlds
     * POST /api/worlds - Create a new managed world
     * GET  /api/worlds/{id} - Get world info
     * DELETE /api/worlds/{id} - Delete a world (requires admin)
     * GET  /api/worlds/{id}/backups - List backups for a world
     * POST /api/worlds/{id}/backups - Create a new backup (with source slot)
     * GET  /api/worlds/{id}/backups/{timestamp} - Get backup info
     * DELETE /api/worlds/{id}/backups/{timestamp} - Delete a backup
     * POST /api/worlds/{id}/backups/{timestamp}/restore - Restore backup to slot
     * GET  /api/worlds/{id}/backups/{timestamp}/export - Export as .mcworld
     */
    private handleWorldsRequest;
    /**
     * Read request body as JSON with size limit and error handling.
     */
    private readRequestBodyJson;
    /**
     * Handle /api/commands/* endpoints for invoking ToolCommands via REST API.
     *
     * Endpoints:
     * GET  /api/commands - List available commands
     * POST /api/commands/{commandName} - Execute a command
     *
     * Request body for POST (JSON):
     * {
     *   "args": ["arg1", "arg2"],
     *   "flags": { "session": "mySession", "traits": ["tameable"] }
     * }
     *
     * Response (JSON):
     * {
     *   "success": true/false,
     *   "message": "...",
     *   "data": { ... },
     *   "error": { "code": "...", "message": "..." }
     * }
     */
    private handleCommandsRequest;
    getMainContent(req: http.IncomingMessage): string;
}
