import { randomUUID } from 'node:crypto';
import { log } from '@mondaydotcomorg/atp-runtime';
import { parseBody } from '../core/http.js';
import { handleError, createContext } from '../utils/index.js';
import { runInRequestScope } from '../core/request-scope.js';
export async function handleHTTPRequest(req, res, deps, responseHeaders) {
    const ctx = createContext({
        req,
        cacheProvider: deps.cacheProvider,
        authProvider: deps.authProvider,
        auditSink: deps.auditSink,
        customLogger: deps.customLogger,
        responseHeaders,
    });
    const headers = new Map();
    responseHeaders.set(req, headers);
    if (deps.toolRulesProvider) {
        try {
            ctx.toolRules = deps.toolRulesProvider(ctx);
        }
        catch (error) {
            log.warn('Tool rules provider failed', { error });
        }
    }
    await runInRequestScope({ toolRules: ctx.toolRules }, async () => {
        try {
            if (req.method === 'POST' || req.method === 'PUT') {
                const reqWithBody = req;
                if (reqWithBody.body !== undefined) {
                    ctx.body = reqWithBody.body;
                }
                else {
                    ctx.body = await parseBody(req);
                }
            }
            await runMiddleware(ctx, deps.middleware, deps.routeHandler);
            try {
                if (ctx.clientId && deps.sessionManager && ctx.path !== '/api/init') {
                    try {
                        const newToken = deps.sessionManager.generateToken(ctx.clientId);
                        const expiresAt = Date.now() + 60 * 60 * 1000;
                        headers.set('X-ATP-Token', newToken);
                        headers.set('X-ATP-Token-Expires', expiresAt.toString());
                    }
                    catch (error) { }
                }
                const isStringResponse = typeof ctx.responseBody === 'string';
                res.writeHead(ctx.status, {
                    'Content-Type': isStringResponse ? 'text/plain; charset=utf-8' : 'application/json',
                    ...Object.fromEntries(headers),
                });
                res.end(isStringResponse ? ctx.responseBody : JSON.stringify(ctx.responseBody));
            }
            catch (writeError) { }
        }
        catch (error) {
            try {
                if (ctx.clientId && deps.sessionManager && ctx.path !== '/api/init') {
                    try {
                        const newToken = deps.sessionManager.generateToken(ctx.clientId);
                        const expiresAt = Date.now() + 60 * 60 * 1000;
                        headers.set('X-ATP-Token', newToken);
                        headers.set('X-ATP-Token-Expires', expiresAt.toString());
                        log.debug('Token refresh headers set on error', {
                            clientId: ctx.clientId,
                            path: ctx.path,
                            hasSessionManager: !!deps.sessionManager,
                            headerCount: headers.size,
                        });
                    }
                    catch (tokenError) {
                        log.warn('Token refresh failed on error', { error: tokenError });
                    }
                }
                else {
                    log.debug('Token refresh skipped on error', {
                        hasClientId: !!ctx.clientId,
                        hasSessionManager: !!deps.sessionManager,
                        path: ctx.path,
                    });
                }
                handleError(res, error, randomUUID(), headers);
            }
            catch (handlerError) {
                try {
                    if (!res.headersSent) {
                        res.writeHead(500, { 'Content-Type': 'application/json' });
                        res.end(JSON.stringify({ error: 'Internal server error' }));
                    }
                }
                catch { }
            }
        }
        finally {
            responseHeaders.delete(req);
        }
    });
}
async function runMiddleware(ctx, middleware, routeHandler) {
    let index = 0;
    const next = async () => {
        const mw = middleware[index++];
        if (mw) {
            await mw(ctx, next);
        }
        else {
            await routeHandler(ctx);
        }
    };
    await next();
}
//# sourceMappingURL=request-handler.js.map