1<?php
2/**
3 * This file is part of the FreeDSx LDAP package.
4 *
5 * (c) Chad Sikorra <Chad.Sikorra@gmail.com>
6 *
7 * For the full copyright and license information, please view the LICENSE
8 * file that was distributed with this source code.
9 */
10
11namespace FreeDSx\Ldap\Protocol\Queue;
12
13use FreeDSx\Asn1\Encoder\EncoderInterface;
14use FreeDSx\Ldap\Exception\ProtocolException;
15use FreeDSx\Ldap\Exception\UnsolicitedNotificationException;
16use FreeDSx\Ldap\Protocol\LdapMessageRequest;
17use FreeDSx\Ldap\Protocol\LdapMessageResponse;
18use FreeDSx\Ldap\Protocol\LdapQueue;
19use FreeDSx\Socket\Exception\ConnectionException;
20use FreeDSx\Socket\Queue\Message;
21use FreeDSx\Socket\SocketPool;
22
23/**
24 * The LDAP Queue class for sending and receiving messages for clients.
25 *
26 * @author Chad Sikorra <Chad.Sikorra@gmail.com>
27 */
28class ClientQueue extends LdapQueue
29{
30    /**
31     * @var bool
32     */
33    protected $shouldReconnect = false;
34
35    /**
36     * @var SocketPool
37     */
38    protected $socketPool;
39
40    /**
41     * @throws ConnectionException
42     */
43    public function __construct(SocketPool $socketPool, EncoderInterface $encoder = null)
44    {
45        $this->socketPool = $socketPool;
46        parent::__construct($socketPool->connect(), $encoder);
47    }
48
49    /**
50     * @throws ProtocolException
51     * @throws UnsolicitedNotificationException
52     * @throws ConnectionException
53     */
54    public function getMessage(?int $id = null): LdapMessageResponse
55    {
56        $this->initSocket();
57
58        $message = $this->getAndValidateMessage($id);
59        if (!$message instanceof LdapMessageResponse) {
60            throw new ProtocolException(sprintf(
61                'Expected an instance of LdapMessageResponse but got: %s',
62                get_class($message)
63            ));
64        }
65
66        return $message;
67    }
68
69    /**
70     * {@inheritDoc}
71     */
72    public function getMessages(?int $id = null)
73    {
74        $this->initSocket();
75
76        return parent::getMessages($id);
77    }
78
79    public function sendMessage(LdapMessageRequest ...$messages): ClientQueue
80    {
81        $this->initSocket();
82        $this->sendLdapMessage(...$messages);
83
84        return $this;
85    }
86
87    /**
88     * {@inheritDoc}
89     */
90    public function close(): void
91    {
92        parent::close();
93        $this->shouldReconnect = true;
94    }
95
96    /**
97     * @throws ConnectionException
98     */
99    protected function initSocket(): void
100    {
101        if ($this->shouldReconnect) {
102            $this->socket = $this->socketPool->connect();
103            $this->shouldReconnect = false;
104        }
105    }
106
107    /**
108     * {@inheritDoc}
109     */
110    protected function constructMessage(Message $message, ?int $id = null)
111    {
112        return LdapMessageResponse::fromAsn1($message->getMessage());
113    }
114}
115