import type { MiddlewareHandler } from 'hono';
import * as errors from '../custom-errors';
import { isProxiedPath } from '../sidecar/proxied-prefixes';

export const bodyParser: () => MiddlewareHandler = () => async (ctx, next) => {
  // Sidecar proxy routes: the body is forwarded verbatim and never read here. Consuming it would be
  // pointless for JSON and destructive for multipart — see sidecar/proxied-prefixes.ts for why a parsed
  // multipart body cannot be forwarded intact.
  if (isProxiedPath(ctx.req.path)) {
    ctx.set('body', {});
    return next();
  }

  if (!['POST', 'PUT', 'PATCH'].includes(ctx.req.method.toUpperCase())) {
    ctx.set('body', {});
    return next();
  }

  const contentType = ctx.req.header('Content-Type') || '';

  try {
    if (contentType.includes('application/json')) {
      const text = await ctx.req.text();
      const body = text ? JSON.parse(text) : {};
      ctx.set('body', body);
    } else if (contentType.includes('application/x-www-form-urlencoded')) {
      const body = await ctx.req.parseBody();
      ctx.set('body', body);
    } else if (contentType.includes('multipart/form-data')) {
      const body = await ctx.req.parseBody({ all: true });
      ctx.set('body', body);
    } else {
      // No recognized content type, set empty body
      ctx.set('body', {});
    }
  } catch {
    // Previously swallowed, which left `body` unset — handlers then destructured undefined and the
    // client got a 500 for what is squarely a malformed request.
    throw errors.BAD_REQUEST('Invalid request body');
  }

  return next();
};
