1<?php
2/* Icinga Web 2 | (c) 2016 Icinga Development Team | GPLv2+ */
3
4namespace Icinga\Module\Monitoring\Plugin;
5
6/**
7 * The warning/critical threshold of a measured value
8 */
9class ThresholdRange
10{
11    /**
12     * The smallest value inside the range (null stands for -∞)
13     *
14     * @var float|null
15     */
16    protected $min;
17
18    /**
19     * The biggest value inside the range (null stands for ∞)
20     *
21     * @var float|null
22     */
23    protected $max;
24
25    /**
26     * Whether to invert the result of contains()
27     *
28     * @var bool
29     */
30    protected $inverted = false;
31
32    /**
33     * The unmodified range as passed to fromString()
34     *
35     * @var string
36     */
37    protected $raw;
38
39    /**
40     * Create a new instance based on a threshold range conforming to <https://nagios-plugins.org/doc/guidelines.html>
41     *
42     * @param   string  $rawRange
43     *
44     * @return  ThresholdRange
45     */
46    public static function fromString($rawRange)
47    {
48        $range = new static();
49        $range->raw = $rawRange;
50
51        if ($rawRange == '') {
52            return $range;
53        }
54
55        $rawRange = ltrim($rawRange);
56        if (substr($rawRange, 0, 1) === '@') {
57            $range->setInverted();
58            $rawRange = substr($rawRange, 1);
59        }
60
61        if (strpos($rawRange, ':') === false) {
62            $min = 0.0;
63            $max = floatval(trim($rawRange));
64        } else {
65            list($min, $max) = explode(':', $rawRange, 2);
66            $min = trim($min);
67            $max = trim($max);
68
69            switch ($min) {
70                case '':
71                    $min = 0.0;
72                    break;
73                case '~':
74                    $min = null;
75                    break;
76                default:
77                    $min = floatval($min);
78            }
79
80            $max = empty($max) ? null : floatval($max);
81        }
82
83        return $range->setMin($min)
84            ->setMax($max);
85    }
86
87    /**
88     * Set the smallest value inside the range (null stands for -∞)
89     *
90     * @param   float|null  $min
91     *
92     * @return  $this
93     */
94    public function setMin($min)
95    {
96        $this->min = $min;
97        return $this;
98    }
99
100    /**
101     * Get the smallest value inside the range (null stands for -∞)
102     *
103     * @return  float|null
104     */
105    public function getMin()
106    {
107        return $this->min;
108    }
109
110    /**
111     * Set the biggest value inside the range (null stands for ∞)
112     *
113     * @param   float|null  $max
114     *
115     * @return  $this
116     */
117    public function setMax($max)
118    {
119        $this->max = $max;
120        return $this;
121    }
122
123    /**
124     * Get the biggest value inside the range (null stands for ∞)
125     *
126     * @return  float|null
127     */
128    public function getMax()
129    {
130        return $this->max;
131    }
132
133    /**
134     * Set whether to invert the result of contains()
135     *
136     * @param   bool    $inverted
137     *
138     * @return  $this
139     */
140    public function setInverted($inverted = true)
141    {
142        $this->inverted = $inverted;
143        return $this;
144    }
145
146    /**
147     * Get whether to invert the result of contains()
148     *
149     * @return  bool
150     */
151    public function isInverted()
152    {
153        return $this->inverted;
154    }
155
156    /**
157     * Return whether $value is inside $this
158     *
159     * @param   float   $value
160     *
161     * @return  bool
162     */
163    public function contains($value)
164    {
165        return (bool) ($this->inverted ^ (
166            ($this->min === null || $this->min <= $value) && ($this->max === null || $this->max >= $value)
167        ));
168    }
169
170    /**
171     * Return the textual representation of $this, suitable for fromString()
172     *
173     * @return  string
174     */
175    public function __toString()
176    {
177        return (string) $this->raw;
178    }
179}
180