<?php

namespace apexl\Io\middleware\bodyParser;

use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface as RequestHandler;

class bodyParserController implements MiddlewareInterface
{
    public function process(Request $request, RequestHandler $handler): Response
    {
        $contentType = $request->getHeaderLine('Content-Type');

        if (strstr($contentType, 'application/json') || strstr($contentType, 'text/plain')) {
            $contents = $request->getBody()->getContents();
            //prevent errors for blank strings.
            $contents = json_decode((empty($contents) ? "{}" : $contents));
            if (json_last_error() === JSON_ERROR_NONE) {
                $request = $request->withParsedBody($contents);
            } else {
                $this->meaningfulJsonError(json_last_error());
            }
        }

        return $handler->handle($request);
    }

    /**
     * @param $errorInt
     * @throws \Exception
     */
    protected function meaningfulJsonError($errorInt)
    {
        $error = match ($errorInt) {
            JSON_ERROR_DEPTH => 'Maximum stack depth exceeded',
            JSON_ERROR_STATE_MISMATCH => 'Underflow or the modes mismatch',
            JSON_ERROR_CTRL_CHAR => 'Unexpected control character found',
            JSON_ERROR_SYNTAX => 'Syntax error, malformed JSON',
            JSON_ERROR_UTF8 => 'Malformed UTF-8 characters, possibly incorrectly encoded',
            default => "Unknown JSON Parsing error",
        };
        throw new \Exception("The provided JSON is invalid | ".$error);
    }
}
