1<?php
2
3declare(strict_types=1);
4
5namespace Nyholm\Dsn\Configuration;
6
7/**
8 * A function with one or more arguments. The default function is called "dsn".
9 * Other function may be "failover" or "roundrobin".
10 *
11 * Examples:
12 * - failover(redis://localhost memcached://example.com)
13 * - dsn(amqp://guest:password@localhost:1234)
14 * - foobar(amqp://guest:password@localhost:1234 amqp://localhost)?delay=10
15 *
16 * @author Tobias Nyholm <tobias.nyholm@gmail.com>
17 */
18class DsnFunction
19{
20    /**
21     * @var string
22     */
23    private $name;
24
25    /**
26     * @var array
27     */
28    private $arguments;
29
30    /**
31     * @var array
32     */
33    private $parameters;
34
35    public function __construct(string $name, array $arguments, array $parameters = [])
36    {
37        $this->name = $name;
38        $this->arguments = $arguments;
39        $this->parameters = $parameters;
40    }
41
42    public function getName(): string
43    {
44        return $this->name;
45    }
46
47    /**
48     * @return array<DsnFunction|Dsn>
49     */
50    public function getArguments(): array
51    {
52        return $this->arguments;
53    }
54
55    public function getParameters(): array
56    {
57        return $this->parameters;
58    }
59
60    /**
61     * @param mixed|null $default
62     *
63     * @return mixed
64     */
65    public function getParameter(string $key, $default = null)
66    {
67        return \array_key_exists($key, $this->parameters) ? $this->parameters[$key] : $default;
68    }
69
70    /**
71     * @param mixed $value
72     *
73     * @return static
74     */
75    public function withParameter(string $key, $value)
76    {
77        $new = clone $this;
78        $new->parameters[$key] = $value;
79
80        return $new;
81    }
82
83    /**
84     * @return static
85     */
86    public function withoutParameter(string $key)
87    {
88        $new = clone $this;
89        unset($new->parameters[$key]);
90
91        return $new;
92    }
93
94    /**
95     * @return DsnFunction|Dsn
96     */
97    public function first()
98    {
99        return reset($this->arguments);
100    }
101
102    /**
103     * @return string
104     */
105    public function __toString()
106    {
107        return sprintf('%s(%s)%s', $this->getName(), implode(' ', $this->getArguments()), empty($this->parameters) ? '' : '?'.http_build_query($this->parameters));
108    }
109}
110