<?php

declare(strict_types=1);

namespace App\Framework\Http;

/**
 * Helper class for manipulating HTTP requests without modifying the original request objects
 */
final readonly class RequestManipulator
{
    /**
     * Create a new request with an additional header
     */
    public function withHeader(HttpRequest $request, string $name, string $value): HttpRequest
    {
        $newHeaders = $request->headers->with($name, $value);

        return new HttpRequest(
            method: $request->method,
            headers: $newHeaders,
            body: $request->body,
            path: $request->path,
            queryParams: $request->queryParams,
            files: $request->files,
            cookies: $request->cookies,
            server: $request->server,
            id: $request->id,
            parsedBody: $request->parsedBody,
        );
    }

    /**
     * Create a new request with updated headers
     */
    public function withHeaders(HttpRequest $request, Headers $headers): HttpRequest
    {
        return new HttpRequest(
            method: $request->method,
            headers: $headers,
            body: $request->body,
            path: $request->path,
            queryParams: $request->queryParams,
            files: $request->files,
            cookies: $request->cookies,
            server: $request->server,
            id: $request->id,
            parsedBody: $request->parsedBody,
        );
    }

    /**
     * Create a new request without a specific header
     */
    public function withoutHeader(HttpRequest $request, string $name): HttpRequest
    {
        $newHeaders = $request->headers->without($name);

        return new HttpRequest(
            method: $request->method,
            headers: $newHeaders,
            body: $request->body,
            path: $request->path,
            queryParams: $request->queryParams,
            files: $request->files,
            cookies: $request->cookies,
            server: $request->server,
            id: $request->id,
            parsedBody: $request->parsedBody,
        );
    }

    /**
     * Create a new request with multiple headers added
     */
    public function withAddedHeaders(HttpRequest $request, array $headers): HttpRequest
    {
        $newHeaders = $request->headers;

        foreach ($headers as $name => $value) {
            $newHeaders = $newHeaders->with($name, $value);
        }

        return new HttpRequest(
            method: $request->method,
            headers: $newHeaders,
            body: $request->body,
            path: $request->path,
            queryParams: $request->queryParams,
            files: $request->files,
            cookies: $request->cookies,
            server: $request->server,
            id: $request->id,
            parsedBody: $request->parsedBody,
        );
    }
}
