import { getMissingHeaders } from "./get-missing-headers";
import { getPayload } from "./get-payload";
async function middleware(webhooks, options, request, response, next) {
  let pathname;
  try {
    pathname = new URL(request.url, "http://localhost").pathname;
  } catch (error) {
    response.writeHead(422, {
      "content-type": "application/json"
    });
    response.end(
      JSON.stringify({
        error: `Request URL could not be parsed: ${request.url}`
      })
    );
    return;
  }
  const isUnknownRoute = request.method !== "POST" || pathname !== options.path;
  const isExpressMiddleware = typeof next === "function";
  if (isUnknownRoute) {
    if (isExpressMiddleware) {
      return next();
    } else {
      return options.onUnhandledRequest(request, response);
    }
  }
  if (!request.headers["content-type"] || !request.headers["content-type"].startsWith("application/json")) {
    response.writeHead(415, {
      "content-type": "application/json",
      accept: "application/json"
    });
    response.end(
      JSON.stringify({
        error: `Unsupported "Content-Type" header value. Must be "application/json"`
      })
    );
    return;
  }
  const missingHeaders = getMissingHeaders(request).join(", ");
  if (missingHeaders) {
    response.writeHead(400, {
      "content-type": "application/json"
    });
    response.end(
      JSON.stringify({
        error: `Required headers missing: ${missingHeaders}`
      })
    );
    return;
  }
  const eventName = request.headers["x-github-event"];
  const signatureSHA256 = request.headers["x-hub-signature-256"];
  const id = request.headers["x-github-delivery"];
  options.log.debug(`${eventName} event received (id: ${id})`);
  let didTimeout = false;
  const timeout = setTimeout(() => {
    didTimeout = true;
    response.statusCode = 202;
    response.end("still processing\n");
  }, 9e3).unref();
  try {
    const payload = await getPayload(request);
    await webhooks.verifyAndReceive({
      id,
      name: eventName,
      payload,
      signature: signatureSHA256
    });
    clearTimeout(timeout);
    if (didTimeout)
      return;
    response.end("ok\n");
  } catch (error) {
    clearTimeout(timeout);
    if (didTimeout)
      return;
    const err = Array.from(error)[0];
    const errorMessage = err.message ? `${err.name}: ${err.message}` : "Error: An Unspecified error occurred";
    response.statusCode = typeof err.status !== "undefined" ? err.status : 500;
    options.log.error(error);
    response.end(
      JSON.stringify({
        error: errorMessage
      })
    );
  }
}
export {
  middleware
};
