#!/usr/bin/env node
/**
 * HTTP Server Entry Point for Vaspera MCP
 *
 * This provides an HTTP interface for the MCP server, allowing
 * the web frontend to call MCP tools via REST/streaming API.
 *
 * Usage:
 *   node dist/http-server.js
 *   # or with tsx for development:
 *   npx tsx src/http-server.ts
 */
import { createServer } from "http";
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
import { server } from "./index.js";
import { logger } from "./logger.js";
// Railway uses PORT, local dev uses MCP_HTTP_PORT
const PORT = parseInt(process.env.PORT || process.env.MCP_HTTP_PORT || "3002", 10);
const FRONTEND_URL = process.env.FRONTEND_URL || "http://localhost:3001";
const CORS_ORIGIN = process.env.CORS_ORIGIN || FRONTEND_URL;
/**
 * Set CORS headers for cross-origin requests from the frontend
 */
function setCorsHeaders(res) {
    res.setHeader("Access-Control-Allow-Origin", CORS_ORIGIN);
    res.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
    res.setHeader("Access-Control-Allow-Headers", "Content-Type, Accept, X-Session-Id");
    res.setHeader("Access-Control-Allow-Credentials", "true");
    res.setHeader("Access-Control-Max-Age", "86400");
}
/**
 * Handle incoming HTTP requests and route to MCP transport
 */
async function handleRequest(req, res) {
    setCorsHeaders(res);
    // Handle CORS preflight
    if (req.method === "OPTIONS") {
        res.writeHead(204);
        res.end();
        return;
    }
    // Health check endpoint
    if (req.url === "/health" && req.method === "GET") {
        res.writeHead(200, { "Content-Type": "application/json" });
        res.end(JSON.stringify({ status: "ok", server: "vaspera-mcp", version: "2.0.0" }));
        return;
    }
    // MCP endpoint
    if (req.url === "/mcp" || req.url === "/") {
        try {
            const sessionId = req.headers["x-session-id"];
            const transport = new StreamableHTTPServerTransport({
                sessionIdGenerator: () => sessionId || crypto.randomUUID(),
            });
            // Connect the transport to our server
            await server.connect(transport);
            // Handle the HTTP request through the transport
            await transport.handleRequest(req, res);
            logger.info("http.request.handled", {
                method: req.method,
                url: req.url,
                sessionId,
            });
        }
        catch (error) {
            logger.error("http.request.error", {
                error: error instanceof Error ? error.message : String(error),
            });
            if (!res.headersSent) {
                res.writeHead(500, { "Content-Type": "application/json" });
                res.end(JSON.stringify({ error: "Internal server error" }));
            }
        }
        return;
    }
    // 404 for unknown routes
    res.writeHead(404, { "Content-Type": "application/json" });
    res.end(JSON.stringify({ error: "Not found", path: req.url }));
}
/**
 * Start the HTTP server
 */
async function main() {
    logger.info("http-server.starting", { port: PORT, cors: CORS_ORIGIN });
    const httpServer = createServer(handleRequest);
    httpServer.listen(PORT, () => {
        logger.info("http-server.started", {
            port: PORT,
            url: `http://localhost:${PORT}`,
            endpoints: {
                mcp: `http://localhost:${PORT}/mcp`,
                health: `http://localhost:${PORT}/health`,
            },
        });
        console.log(`
╔═══════════════════════════════════════════════════════════╗
║                  Vaspera MCP HTTP Server                  ║
╠═══════════════════════════════════════════════════════════╣
║  Status:    Running                                       ║
║  Port:      ${String(PORT).padEnd(44)}║
║  MCP:       http://localhost:${PORT}/mcp${" ".repeat(26 - String(PORT).length)}║
║  Health:    http://localhost:${PORT}/health${" ".repeat(23 - String(PORT).length)}║
╚═══════════════════════════════════════════════════════════╝
`);
    });
    // Graceful shutdown
    process.on("SIGINT", () => {
        logger.info("http-server.shutdown", { signal: "SIGINT" });
        httpServer.close(() => {
            logger.info("http-server.closed");
            process.exit(0);
        });
    });
    process.on("SIGTERM", () => {
        logger.info("http-server.shutdown", { signal: "SIGTERM" });
        httpServer.close(() => {
            logger.info("http-server.closed");
            process.exit(0);
        });
    });
}
main().catch((error) => {
    logger.error("http-server.fatal", {
        error: error instanceof Error ? error.message : String(error),
    });
    process.exit(1);
});
//# sourceMappingURL=http-server.js.map