<?php

namespace App\Framework\Queue;

use App\Framework\Cache\Serializer;
use App\Framework\Cache\Serializer\PhpSerializer;
use Predis\Client as Redis;

final class RedisQueue implements Queue
{
    private Redis $redis;
    private string $queueName;

    public function __construct(
        string $queueName = 'commands',
        string $host = '127.0.0.1',
        int $port = 6379,
        ?string $password = null,
        int $db = 0,
        private readonly Serializer $serializer = new PhpSerializer
    ) {
        $this->queueName = $queueName;
        $this->redis = new Redis([
            'scheme' => 'tcp',
            'host'   => $host,
            'port'   => $port,
            'timeout' => 1.0,
            'read_write_timeout' => 0,
        ]);
        $this->redis->connect();
        if ($password) {
            $this->redis->auth($password);
        }
        $this->redis->select($db);
    }

    public function push(object $job): void
    {
        $data = $this->serializer->serialize($job);
        $this->redis->rpush($this->queueName, [$data]);
    }

    public function pop(): ?object
    {
        // Wartet bis zu 2 Sekunden auf einen neuen Job (blocking)
        $result = $this->redis->blpop($this->queueName, 2);

        if ($result && isset($result[1])) {
            return $this->serializer->unserialize($result[1]);
        }
        return null;
    }
}
