Completed
Pull Request — master (#42)
by Frederik
03:52
created

AggregateResponse::withLine()   B

Complexity

Conditions 5
Paths 6

Size

Total Lines 34
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

Changes 0
Metric Value
dl 0
loc 34
c 0
b 0
f 0
ccs 0
cts 30
cp 0
rs 8.439
cc 5
eloc 23
nc 6
nop 1
crap 30
1
<?php
2
declare(strict_types=1);
3
4
namespace Genkgo\Mail\Protocol\Imap\Response;
5
6
use Genkgo\Mail\Exception\AssertionFailedException;
7
use Genkgo\Mail\Protocol\Imap\RequestInterface;
8
use Genkgo\Mail\Protocol\Imap\ResponseInterface;
9
10
/**
11
 * Class Response
12
 * @package Genkgo\Mail\Protocol\Smtp
13
 */
14
final class AggregateResponse implements \IteratorAggregate
15
{
16
    /**
17
     * @var array|ResponseInterface[]
18
     */
19
    private $lines = [];
20
21
    /**
22
     * @var RequestInterface
23
     */
24
    private $request;
25
26
    /**
27
     * Reply constructor.
28
     * @param RequestInterface $request
29
     */
30
    public function __construct(RequestInterface $request)
31
    {
32
        $this->request = $request;
33
    }
34
35
    /**
36
     * @return \Iterator|ResponseInterface[]
37
     */
38
    public function getIterator(): \Iterator
39
    {
40
        return new \ArrayIterator($this->lines);
41
    }
42
43
    /**
44
     * @return ResponseInterface
45
     */
46
    public function first(): ResponseInterface
47
    {
48
        if (empty($this->lines)) {
49
            throw new \UnexpectedValueException('Cannot return item of empty response');
50
        }
51
52
        return reset($this->lines);
53
    }
54
55
    /**
56
     * @return ResponseInterface
57
     */
58
    public function last(): ResponseInterface
59
    {
60
        if (empty($this->lines)) {
61
            throw new \UnexpectedValueException('Cannot return item of empty response');
62
        }
63
64
        return end($this->lines);
65
    }
66
67
    /**
68
     * @param int $index
69
     * @return ResponseInterface
70
     */
71
    public function at(int $index): ResponseInterface
72
    {
73
        if (!isset($this->lines[$index])) {
74
            throw new \UnexpectedValueException('Item not in response');
75
        }
76
77
        return $this->lines[$index];
78
    }
79
80
    /**
81
     * @return bool
82
     */
83
    public function hasCompleted(): bool
84
    {
85
        if (empty($this->lines)) {
86
            return false;
87
        }
88
89
        $lastCommand = end($this->lines);
90
        try {
91
            $lastCommand->assertTagged();
92
            return true;
93
        } catch (AssertionFailedException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
94
        }
95
96
        try {
97
            $lastCommand->assertContinuation();
98
            return true;
99
        } catch (AssertionFailedException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
100
        }
101
102
        return false;
103
    }
104
105
    /**
106
     * @param string $line
107
     * @return AggregateResponse
108
     */
109
    public function withLine(string $line): AggregateResponse
110
    {
111
        $clone = clone $this;
112
113
        if (!isset($line[0])) {
114
            throw new \InvalidArgumentException('Empty line');
115
        }
116
117
        switch (substr($line, 0, 2)) {
118
            case '+ ':
119
                $clone->lines[] = new CommandContinuationRequestResponse(
120
                    substr($line, 2)
121
                );
122
                break;
123
            case '* ':
124
                $clone->lines[] = new UntaggedResponse(
125
                    substr($line, 2)
126
                );
127
                break;
128
            default:
129
                try {
130
                    $tag = $this->request->getTag();
131
                    $clone->lines[] = new TaggedResponse($tag, $tag->extractBodyFromLine($line));
132
                } catch (\InvalidArgumentException | \BadMethodCallException $e) {
133
                    $keys = array_keys($clone->lines);
134
                    $lastKey = end($keys);
135
                    $clone->lines[$lastKey] = $clone->lines[$lastKey]->withBody($line);
136
                }
137
                break;
138
139
        }
140
141
        return $clone;
142
    }
143
}
144