import { ensureError } from "../../types/errors.js";
import { X_RESTATE_SERVER } from "../../user_agent.js";
import { captureHead, emptyInputReader, tryCreateContextualLogger } from "./utils.js";
import { Buffer } from "node:buffer";
import * as zlib from "node:zlib";

//#region src/endpoint/handlers/lambda.ts
const RESPONSE_COMPRESSION_THRESHOLD = 3 * 1024 * 1024;
var LambdaHandler = class {
	constructor(handler, compressionSupported) {
		this.handler = handler;
		this.compressionSupported = compressionSupported;
	}
	async handleRequest(event, context) {
		const abortController = new AbortController();
		try {
			const path = "path" in event ? event.path : event.rawPath;
			let requestContentEncoding;
			let requestAcceptEncoding;
			for (const [key, value] of Object.entries(event.headers)) if (key.localeCompare("content-encoding", void 0, { sensitivity: "accent" }) === 0) requestContentEncoding = value;
			else if (key.localeCompare("accept-encoding", void 0, { sensitivity: "accent" }) === 0) requestAcceptEncoding = value;
			let inputReader;
			if (!event.body) inputReader = emptyInputReader();
			else {
				let bodyBuffer;
				if (event.isBase64Encoded) bodyBuffer = Buffer.from(event.body, "base64");
				else bodyBuffer = Buffer.from(new TextEncoder().encode(event.body));
				if (requestContentEncoding && requestContentEncoding.includes("zstd")) {
					if (!this.compressionSupported) throw new Error("The input is compressed using zstd, but this lambda deployment doesn't support compression. Make sure to deploy the Lambda using Node > 22");
					bodyBuffer = zlib.zstdDecompressSync(bodyBuffer);
				}
				inputReader = (async function* () {
					yield bodyBuffer;
				})()[Symbol.asyncIterator]();
			}
			const chunks = [];
			const outputWriter = {
				write: function(value) {
					chunks.push(value);
					return Promise.resolve();
				},
				close: function() {
					return Promise.resolve();
				}
			};
			const { writeHead, head: headPromise } = captureHead();
			const response = this.handler.handle({
				headers: event.headers,
				url: path,
				extraArgs: [context]
			}, { AWSRequestId: context.awsRequestId });
			try {
				await response.process({
					inputReader,
					outputWriter,
					writeHead,
					abortSignal: abortController.signal
				});
			} catch (e) {
				const error = ensureError(e);
				(tryCreateContextualLogger(this.handler.endpoint.loggerTransport, path, event.headers) ?? this.handler.endpoint.rlog).error("Unexpected error: " + (error.stack ?? error.message));
				return {
					headers: {
						"content-type": "application/json",
						"x-restate-server": X_RESTATE_SERVER
					},
					statusCode: 500,
					isBase64Encoded: false,
					body: JSON.stringify({ message: error.message })
				};
			}
			const head = await headPromise;
			const responseBodyBuffer = Buffer.concat(chunks);
			let responseBody;
			if (this.compressionSupported && responseBodyBuffer.length > RESPONSE_COMPRESSION_THRESHOLD && requestAcceptEncoding && requestAcceptEncoding.includes("zstd")) {
				head.headers["content-encoding"] = "zstd";
				responseBody = zlib.zstdCompressSync(responseBodyBuffer).toString("base64");
			} else responseBody = responseBodyBuffer.toString("base64");
			return {
				headers: head.headers,
				statusCode: head.statusCode,
				isBase64Encoded: true,
				body: responseBody
			};
		} finally {
			abortController.abort();
		}
	}
};
function isCompressionSupported() {
	return "zstdDecompressSync" in zlib && "zstdCompressSync" in zlib;
}

//#endregion
export { LambdaHandler, isCompressionSupported };
//# sourceMappingURL=lambda.js.map