<?php

namespace Tests\Feature\Api\V1\FullSurface;

use Illuminate\Support\Str;
use Tests\Feature\Api\V1\FullSurface\Support\FullSurfaceE2EContractCase;

class ApiObservabilityRequestIdAndLoggingContractTest extends FullSurfaceE2EContractCase
{
    public function test_api_accepts_correlation_ids_without_echoing_unsafe_values(): void
    {
        $routes = $this->apiRoutesContainingAny(['dashboard', 'attendance', 'finance', 'messages', 'inventory', 'auth/me']);

        foreach ($routes as $route) {
            if ($this->primaryMethod($route) !== 'GET') {
                continue;
            }

            $requestId = (string) Str::uuid();
            $response = $this->actingAs($this->actorFor($route->uri()), 'api')
                ->withHeader('X-Request-Id', $requestId)
                ->getJson($this->materializePath($route->uri()));

            $this->assertControlled($response, 'GET', $route->uri());

            if ($response->headers->has('X-Request-Id')) {
                $this->assertSame($requestId, $response->headers->get('X-Request-Id'));
            }
        }
    }

    public function test_malformed_request_ids_do_not_break_error_handling(): void
    {
        foreach ($this->apiRoutesContainingAny(['login', 'users', 'payments', 'support']) as $route) {
            $method = $this->primaryMethod($route);

            if (! in_array($method, ['POST', 'PUT', 'PATCH'], true)) {
                continue;
            }

            $response = $this->actingAs($this->actorFor($route->uri()), 'api')
                ->withHeader('X-Request-Id', str_repeat('../', 200))
                ->json($method, $this->materializePath($route->uri()), ['invalid' => ['payload' => ['shape']]]);

            $this->assertStatusIn($response, [400, 401, 403, 404, 409, 413, 422], "{$method} {$route->uri()} malformed request id");
            $this->assertStringNotContainsString('../', $response->headers->get('X-Request-Id', ''));
        }
    }
}
