<?php

declare(strict_types=1);

namespace App\Tests\Unit\Shared\Infrastructure\Monitoring;

use App\Shared\Infrastructure\Monitoring\MessengerMetricsCollector;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\Test;
use PHPUnit\Framework\TestCase;
use Prometheus\CollectorRegistry;
use Prometheus\Gauge;
use Symfony\Component\HttpClient\MockHttpClient;
use Symfony\Component\HttpClient\Response\MockResponse;

#[CoversClass(MessengerMetricsCollector::class)]
final class MessengerMetricsCollectorTest extends TestCase
{
    private Gauge $gauge;

    private function createCollector(MockHttpClient $httpClient): MessengerMetricsCollector
    {
        $this->gauge = $this->createMock(Gauge::class);

        $registry = $this->createMock(CollectorRegistry::class);
        $registry->method('getOrRegisterGauge')->willReturn($this->gauge);

        return new MessengerMetricsCollector($registry, $httpClient);
    }

    #[Test]
    public function itSetsGaugeFromRabbitMqResponse(): void
    {
        $response = new MockResponse(json_encode(['messages' => 5]), [
            'http_code' => 200,
        ]);
        $collector = $this->createCollector(new MockHttpClient($response));

        $this->gauge->expects(self::once())
            ->method('set')
            ->with(5.0, ['async']);

        $collector->collect();
    }

    #[Test]
    public function itSkipsGaugeUpdateOnNon200Response(): void
    {
        $response = new MockResponse('Not Found', [
            'http_code' => 404,
        ]);
        $collector = $this->createCollector(new MockHttpClient($response));

        $this->gauge->expects(self::never())->method('set');

        $collector->collect();
    }

    #[Test]
    public function itSkipsGaugeUpdateOnNetworkError(): void
    {
        $response = new MockResponse('', [
            'error' => 'Connection refused',
        ]);
        $collector = $this->createCollector(new MockHttpClient($response));

        $this->gauge->expects(self::never())->method('set');

        $collector->collect();
    }

    #[Test]
    public function itDefaultsToZeroWhenMessagesKeyMissing(): void
    {
        $response = new MockResponse(json_encode(['consumers' => 1]), [
            'http_code' => 200,
        ]);
        $collector = $this->createCollector(new MockHttpClient($response));

        $this->gauge->expects(self::once())
            ->method('set')
            ->with(0.0, ['async']);

        $collector->collect();
    }
}
