summaryrefslogtreecommitdiffstats
path: root/library/Director/DirectorObject/Automation/BasketDiff.php
blob: 8dbb42362d71c3ac1f1804bd286b58aaecd51533 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
<?php

namespace Icinga\Module\Director\DirectorObject\Automation;

use gipfl\Json\JsonString;
use Icinga\Module\Director\Data\Exporter;
use Icinga\Module\Director\Data\ObjectImporter;
use Icinga\Module\Director\Db;
use Icinga\Module\Director\Objects\DirectorDatalist;
use Ramsey\Uuid\UuidInterface;
use stdClass;

class BasketDiff
{
    /** @var Db */
    protected $db;
    /** @var ObjectImporter */
    protected $importer;
    /** @var Exporter */
    protected $exporter;
    /** @var BasketSnapshot */
    protected $snapshot;
    /** @var ?stdClass */
    protected $objects = null;
    /** @var BasketSnapshotFieldResolver */
    protected $fieldResolver;

    public function __construct(BasketSnapshot $snapshot, Db $db)
    {
        $this->db = $db;
        $this->importer = new ObjectImporter($db);
        $this->exporter = new Exporter($db);
        $this->snapshot = $snapshot;
    }

    public function hasChangedFor(string $type, string $key, ?UuidInterface $uuid = null): bool
    {
        return $this->getCurrentString($type, $key, $uuid) !== $this->getBasketString($type, $key);
    }

    public function getCurrentString(string $type, string $key, ?UuidInterface $uuid = null): string
    {
        $current = $this->getCurrent($type, $key, $uuid);
        return $current ? JsonString::encode($current, JSON_PRETTY_PRINT) : '';
    }

    public function getBasketString(string $type, string $key): string
    {
        return JsonString::encode($this->getBasket($type, $key), JSON_PRETTY_PRINT);
    }

    protected function getFieldResolver(): BasketSnapshotFieldResolver
    {
        if ($this->fieldResolver === null) {
            $this->fieldResolver = new BasketSnapshotFieldResolver($this->getBasketObjects(), $this->db);
        }

        return $this->fieldResolver;
    }

    protected function getCurrent(string $type, string $key, ?UuidInterface $uuid = null): ?stdClass
    {
        if ($uuid && $current = BasketSnapshot::instanceByUuid($type, $uuid, $this->db)) {
            $exported = $this->exporter->export($current);
            $this->getFieldResolver()->tweakTargetIds($exported);
        } elseif ($current = BasketSnapshot::instanceByIdentifier($type, $key, $this->db)) {
            $exported = $this->exporter->export($current);
            $this->getFieldResolver()->tweakTargetIds($exported);
        } else {
            $exported = null;
        }
        CompareBasketObject::normalize($exported);

        return $exported;
    }

    protected function getBasket($type, $key): stdClass
    {
        $object = $this->getBasketObject($type, $key);
        $fields = $object->fields ?? null;
        $reExport = $this->exporter->export(
            $this->importer->import(BasketSnapshot::getClassForType($type), $object)
        );
        if ($fields === null) {
            unset($reExport->fields);
        } else {
            $reExport->fields = $fields;
        }
        CompareBasketObject::normalize($reExport);

        return $reExport;
    }

    public function hasCurrentInstance(string $type, string $key, ?UuidInterface $uuid = null): bool
    {
        return $this->getCurrentInstance($type, $key, $uuid) !== null;
    }

    public function getCurrentInstance(string $type, string $key, ?UuidInterface $uuid = null)
    {
        if ($uuid && $instance = BasketSnapshot::instanceByUuid($type, $uuid, $this->db)) {
            return $instance;
        } else {
            return BasketSnapshot::instanceByIdentifier($type, $key, $this->db);
        }
    }

    public function getBasketObjects(): stdClass
    {
        if ($this->objects === null) {
            $this->objects = JsonString::decode($this->snapshot->getJsonDump());
        }

        return $this->objects;
    }

    public function getBasketObject(string $type, string $key): stdClass
    {
        return $this->getBasketObjects()->$type->$key;
    }
}