SimpleMerkele::resetTree()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 5
ccs 4
cts 4
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
crap 1
1
<?php
2
3
namespace Mohamedahmed01\SimpleMerkele;
4
5
use Mohamedahmed01\SimpleMerkele\Types\HashValidation;
6
use Mohamedahmed01\SimpleMerkele\Exceptions\InvalidArrayModeException;
7
use Mohamedahmed01\SimpleMerkele\Exceptions\OddHashInventoryException;
8
use Mohamedahmed01\SimpleMerkele\Exceptions\HashInventoryEmptyException;
9
10
final class SimpleMerkele
11
{
12
    private $inventory = [];
13
    private $topHash = '';
14
    private $array_mode = 2;
15
    private $hashing_algo = 'sha256';
16
    public const ALLOW_ODD_ARRAYS = 1;
17
    public const DIS_ALLOW_ODD_ARRAYS = 2;
18
19 39
    public function __construct($array_mode=2, $hashing_algo='sha256')
20
    {
21 39
        $this->validateArrayMode($array_mode);
22 36
        $this->array_mode = $array_mode;
23 36
        HashValidation::validHashingAlgo($hashing_algo);
24 33
        $this->hashing_algo=$hashing_algo;
25 33
    }
26
    
27 18
    public function addHash(String $hash)
28
    {
29 18
        $this->validateHash($hash, $this->hashing_algo);
30 12
        $this->inventory[]=$hash;
31 12
    }
32
33 15
    public function calculateTree():string
34
    {
35 15
        $this->validateInventory();
36 9
        $this->reduceTree($this->inventory, []);
37 9
        return $this->topHash;
38
    }
39
40 3
    public function resetTree()
41
    {
42 3
        $this->inventory=[];
43 3
        $this->topHash = '';
44 3
    }
45
46 9
    private function reduceTree($treeInventory, $nodeHashesMemo=[])
47
    {
48 9
        $nodeHashes=$nodeHashesMemo;
49 9
        if (count($treeInventory)<=0) {
50 9
            $treeInventory=$nodeHashes;
51 9
            $nodeHashes=[];
52 9
            if (count($treeInventory) <= 1 &&empty($nodeHashes)) {
53 9
                $this->topHash=array_pop($treeInventory);
54 9
                return;
55
            }
56 9
            if (!(count($treeInventory)%2===0)) {
57 9
                $treeInventory[]=$treeInventory[count($treeInventory)-1];
58
            }
59
        }
60 9
        $nodeHashes[] = hash($this->hashing_algo, array_pop($treeInventory).array_pop($treeInventory));
61 9
        $this->reduceTree($treeInventory, $nodeHashes);
62 9
    }
63
64
    /**
65
    * @SuppressWarnings(PHPMD.StaticAccess)
66
    */
67 18
    private function validateHash(String $hash, String $type)
68
    {
69 18
        HashValidation::validateHashString($hash);
70 15
        HashValidation::checkHashLength($hash, $type);
71 12
    }
72
73 15
    private function validateInventory()
74
    {
75 15
        if (empty($this->inventory)) {
76 6
            throw new HashInventoryEmptyException();
77
        }
78 12
        $isOddArray = count($this->inventory)%2 !== 0;
79 12
        if ($this->array_mode === self::ALLOW_ODD_ARRAYS && $isOddArray) {
80 3
            $this->inventory[]=$this->inventory[count($this->inventory)-1];
81 9
        } elseif ($this->array_mode === self::DIS_ALLOW_ODD_ARRAYS && $isOddArray) {
82 3
            throw new OddHashInventoryException();
83
        }
84 9
    }
85
86 39
    private function validateArrayMode($array_mode)
87
    {
88 39
        if (!in_array(
89 39
            $array_mode,
90 39
            [self::ALLOW_ODD_ARRAYS,self::DIS_ALLOW_ODD_ARRAYS],
91 39
            true
92
        )) {
93 3
            throw new InvalidArrayModeException();
94
        }
95 36
    }
96
}
97