Completed
Pull Request — master (#42)
by Frederik
02:22
created

AggregateResponse::withLine()   B

Complexity

Conditions 5
Paths 6

Size

Total Lines 34
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 16
CRAP Score 5.3374

Importance

Changes 0
Metric Value
dl 0
loc 34
ccs 16
cts 21
cp 0.7619
rs 8.439
c 0
b 0
f 0
cc 5
eloc 23
nc 6
nop 1
crap 5.3374
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 4
    public function __construct(RequestInterface $request)
31
    {
32 4
        $this->request = $request;
33 4
    }
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 4
    public function first(): ResponseInterface
47
    {
48 4
        if (empty($this->lines)) {
49
            throw new \UnexpectedValueException('Cannot return item of empty response');
50
        }
51
52 4
        return reset($this->lines);
53
    }
54
55
    /**
56
     * @return ResponseInterface
57
     */
58 4
    public function last(): ResponseInterface
59
    {
60 4
        if (empty($this->lines)) {
61
            throw new \UnexpectedValueException('Cannot return item of empty response');
62
        }
63
64 4
        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('GenericItem not in response');
75
        }
76
77
        return $this->lines[$index];
78
    }
79
80
    /**
81
     * @return bool
82
     */
83 4
    public function hasCompleted(): bool
84
    {
85 4
        if (empty($this->lines)) {
86 4
            return false;
87
        }
88
89 4
        $lastCommand = end($this->lines);
90
        try {
91 4
            $lastCommand->assertTagged();
92 4
            return true;
93 4
        } 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 4
            $lastCommand->assertContinuation();
98 2
            return true;
99 3
        } 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 3
        return false;
103
    }
104
105
    /**
106
     * @param string $line
107
     * @return AggregateResponse
108
     */
109 4
    public function withLine(string $line): AggregateResponse
110
    {
111 4
        $clone = clone $this;
112
113 4
        if (!isset($line[0])) {
114
            throw new \InvalidArgumentException('Empty line');
115
        }
116
117 4
        switch (substr($line, 0, 2)) {
118 4
            case '+ ':
119 2
                $clone->lines[] = new CommandContinuationRequestResponse(
120 2
                    substr($line, 2)
121
                );
122 2
                break;
123 4
            case '* ':
124 3
                $clone->lines[] = new UntaggedResponse(
125 3
                    substr($line, 2)
126
                );
127 3
                break;
128
            default:
129
                try {
130 4
                    $tag = $this->request->getTag();
131 4
                    $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 4
                break;
138
139
        }
140
141 4
        return $clone;
142
    }
143
}
144