Lines 89.65% 26 / 29
Methods 77.77% 7 / 9
Classes 0.00% 0 / 1
Name Lines Methods CRAP
 __construct 100.00% 2 / 2 100.00% 1 / 1 2
 restoreOverrides 0.00% 0 / 2 0.00% 0 / 1 6
 recordOverride 100.00% 5 / 5 100.00% 1 / 1 2
 forgetOverride 100.00% 3 / 3 100.00% 1 / 1 1
 findOverride 100.00% 1 / 1 100.00% 1 / 1 1
 isPaused 100.00% 1 / 1 100.00% 1 / 1 1
 findPause 83.33% 5 / 6 0.00% 0 / 1 4.07
 findConfigPauseOverride 100.00% 2 / 2 100.00% 1 / 1 4
 listPausedAppIds 100.00% 7 / 7 100.00% 1 / 1 1
16final class AppPauseRegistry
17{
18    /** @var array<string, AppId> */
19    private array $configPausedAppIds = [];
20
21    /** @var array<string, AppPauseOverride> */
22    private array $overrides = [];
23
24    public function __construct(
25        AppDefinitionCollection $enabledApps,
26        private readonly DaemonStartTime $startTime,
27    ) {
28        foreach ($enabledApps->filter(static fn(AppDefinition $app): bool => $app->startsPaused) as $app) {
29            $this->configPausedAppIds[$app->id->value] = $app->id;
30        }
31    }
32
33    public function restoreOverrides(AppPauseOverrideCollection $overrides): void
34    {
35        foreach ($overrides as $override) {
36            $this->overrides[$override->appId->value] = $override;
37        }
38    }
39
40    public function recordOverride(AppPauseOverride $override): bool
41    {
42        $changed = $this->isPaused($override->appId) !== $override->paused;
43
44        if ($changed) {
45            unset($this->overrides[$override->appId->value]);
46        }
47
48        $this->overrides[$override->appId->value] = $override;
49
50        return $changed;
51    }
52
53    public function forgetOverride(AppId $appId): bool
54    {
55        $existed = isset($this->overrides[$appId->value]);
56        unset($this->overrides[$appId->value]);
57
58        return $existed;
59    }
60
61    public function findOverride(AppId $appId): ?AppPauseOverride
62    {
63        return $this->overrides[$appId->value] ?? null;
64    }
65
66    public function isPaused(AppId $appId): bool
67    {
68        return $this->findOverride($appId)->paused ?? isset($this->configPausedAppIds[$appId->value]);
69    }
70
71    public function findPause(AppId $appId): ?AppPause
72    {
73        $override = $this->findOverride($appId);
74
75        if ($override !== null) {
76            return $override->paused ? new AppPause($appId, $override->since, $override->source) : null;
77        }
78
79        if (isset($this->configPausedAppIds[$appId->value])) {
80            // A config pause holds from daemon start, which is recorded after this registry is built.
81            return new AppPause($appId, $this->startTime->getStartedAt(), AppPauseSource::Config);
82        }
83
84        return null;
85    }
86
87    public function findConfigPauseOverride(AppId $appId): ?AppPauseOverride
88    {
89        $override = $this->findOverride($appId);
90
91        return $override !== null && !$override->paused && isset($this->configPausedAppIds[$appId->value]) ? $override : null;
92    }
93
94    public function listPausedAppIds(): AppIdCollection
95    {
96        return AppIdCollection::fromList([
97            ...array_values(array_diff_key($this->configPausedAppIds, $this->overrides)),
98            ...array_map(
99                static fn(AppPauseOverride $override): AppId => $override->appId,
100                array_values(array_filter($this->overrides, static fn(AppPauseOverride $override): bool => $override->paused)),
101            ),
102        ]);
103    }
104}