Failed Conditions
Pull Request — 0.3 (#20)
by jean
03:05
created

StatCliDumper::dumpTable()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 28

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 18
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 2
dl 0
loc 28
ccs 18
cts 18
cp 1
crap 2
rs 9.472
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Darkilliant\ProcessBundle\StatDumper;
6
7
use Symfony\Component\Console\Style\SymfonyStyle;
8
9
class StatCliDumper
10
{
11
    const TABLE_HEADERS = ['class', '01 BEST', '02 BEST', '03 BEST', '01 BAD', '02 BAD', '03 BAD', 'TOTAL RUN', 'TOTAL WAIT'];
12
13
    private $max = null;
14
15 1
    public function dump(array $stats, SymfonyStyle $outputHelper)
16
    {
17 1
        $this->dumpTable($outputHelper, $stats);
18 1
        $this->dumpPipe($outputHelper, $stats);
19
20 1
        $outputHelper->writeln('');
21 1
    }
22
23 1
    private function dumpTable(SymfonyStyle $outputHelper, array $stats)
24
    {
25 1
        $lines = [];
26 1
        $this->max = max(array_column($stats, 'global'));
27
28 1
        foreach ($stats as $class => $values) {
29 1
            $class = $this->getShortClassName($class);
30
31
            // Fetch times and format for display
32 1
            $times = array_merge(
33 1
                array_pad($values['best_times'], 3, -1),
34 1
                array_pad($values['bad_times'], 3, -1),
35 1
                [$values['global'], $values['global_wait']]
36
            );
37 1
            $times = $this->formatTimes($times);
38
39 1
            $title = sprintf(
40 1
                '%s. (%s) %s (%sx)',
41 1
                $values['position'],
42 1
                $values['tendance'],
43 1
                $class,
44 1
                number_format($values['count_iteration'])
45
            );
46
47 1
            $lines[] = array_merge([$title], $times);
48
        }
49
50 1
        $outputHelper->table(self::TABLE_HEADERS, $lines);
51 1
    }
52
53 1
    private function dumpPipe(SymfonyStyle $outputHelper, array $stats)
54
    {
55 1
        $outputHelper->write($this->generatePipe($stats));
56 1
    }
57
58 1
    private function formatTimes(array $times): array
59
    {
60
        // Best times
61 1
        $times[0] = $this->formatTime($times[0], 100);
62 1
        $times[1] = $this->formatTime($times[1], 100);
63 1
        $times[2] = $this->formatTime($times[2], 100);
64
65
        // Bad times
66 1
        $times[3] = $this->formatTime($times[3], 100);
67 1
        $times[4] = $this->formatTime($times[4], 100);
68 1
        $times[5] = $this->formatTime($times[5], 100);
69
70
        // Total run
71 1
        $times[6] = $this->formatTime($times[6]);
72
        // Total wait
73 1
        $times[7] = $this->formatTime($times[7]);
74
75 1
        return $times;
76
    }
77
78 1
    private function formatTime($time, $seuil = null): string
79
    {
80 1
        $time = (int) $time;
81 1
        if (-1 === $time) {
82 1
            return '~ ms';
83
        }
84
85 1
        return (($seuil && $time > $seuil) || $time == $this->max) ? '<error>'.$time.' ms</error>' : $time.' ms';
86
    }
87
88 1
    private function getShortClassName(string $fqcn): string
89
    {
90 1
        $path = explode('\\', $fqcn);
91
92 1
        return array_pop($path);
93
    }
94
95 1
    private function generatePipe($stats)
96
    {
97 1
        $waits = array_combine(array_keys($stats), array_column($stats, 'global_wait'));
98 1
        $maxWait = max($waits);
99
100
        // Convert all wait times to float
101
        $waits = array_map(function ($item) { return (int) $item; }, $waits);
102
        // Skip tasks not wait
103
        $waits = array_filter($waits, function ($item) { return 0 != $item; });
104
105 1
        $reference = $maxWait / 100;
106
107 1
        $pipe = [];
108
109 1
        foreach ($waits as $class => $ms) {
110 1
            $countPercents = (int) ($ms / $reference);
111
112 1
            if ($countPercents < 1) {
113 1
                $countPercents = 1;
114
            }
115
116 1
            $pipe = array_merge($pipe, $this->generatePartPipe($class, $countPercents));
117
        }
118
119 1
        return implode(PHP_EOL, $pipe);
120
    }
121
122 1
    private function generatePartPipe($class, $countPercents)
123
    {
124 1
        $pipe = [];
125
126
        // Create one part of pipe for represente speed of task
127 1
        $pipe = array_merge($pipe, array_pad([], 9, $this->generateBar($countPercents)));
128 1
        $pipe = array_merge($pipe, [$this->generateBarClass($class, $countPercents)]);
129 1
        $pipe = array_merge($pipe, array_pad([], 9, $this->generateBar($countPercents)));
130
131 1
        return $pipe;
132
    }
133
134 1
    private function generateBar(int $countPercents): string
135
    {
136 1
        $bar = str_repeat(' ', 10);
137 1
        $bar .= str_repeat(' ', (int) ((100 - $countPercents) / 2));
138 1
        $bar .= "\e[32m\e[42m".str_repeat('#', $countPercents)."\e[0m";
139
140 1
        return $bar;
141
    }
142
143 1
    private function generateBarClass(string $class, int $countPercents): string
144
    {
145 1
        $size = strlen($class);
146 1
        $bar = str_repeat(' ', 10);
147 1
        $bar .= str_repeat(' ', (int) ((100 - $countPercents) / 2));
148 1
        $bar .= "\e[42m".$class."\e[0m";
149 1
        if ($countPercents > $size) {
150 1
            $bar .= "\e[32m\e[42m".str_repeat('#', $countPercents - $size)."\e[0m";
151
        }
152
153 1
        return $bar;
154
    }
155
}
156