1/*
2** Zabbix
3** Copyright (C) 2001-2021 Zabbix SIA
4**
5** This program is free software; you can redistribute it and/or modify
6** it under the terms of the GNU General Public License as published by
7** the Free Software Foundation; either version 2 of the License, or
8** (at your option) any later version.
9**
10** This program is distributed in the hope that it will be useful,
11** but WITHOUT ANY WARRANTY; without even the implied warranty of
12** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13** GNU General Public License for more details.
14**
15** You should have received a copy of the GNU General Public License
16** along with this program; if not, write to the Free Software
17** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18**/
19
20// Package metric provides an interface for describing a schema of metric's parameters.
21package metric
22
23import (
24	"fmt"
25	"regexp"
26	"strconv"
27	"strings"
28)
29
30type Validator interface {
31	Validate(value *string) error
32}
33
34type SetValidator struct {
35	Set             []string
36	CaseInsensitive bool
37}
38
39func (v SetValidator) Validate(value *string) error {
40	if v.Set != nil && len(v.Set) == 0 {
41		panic("set cannot be empty")
42	}
43
44	if value == nil {
45		return nil
46	}
47
48	for _, s := range v.Set {
49		if (v.CaseInsensitive && strings.ToLower(*value) == strings.ToLower(s)) || (!v.CaseInsensitive && *value == s) {
50			return nil
51		}
52	}
53
54	return fmt.Errorf("allowed values: %s", strings.Join(v.Set, ", "))
55}
56
57type PatternValidator struct {
58	Pattern string
59}
60
61func (v PatternValidator) Validate(value *string) error {
62	if value == nil {
63		return nil
64	}
65
66	b, err := regexp.MatchString(v.Pattern, *value)
67	if err != nil {
68		return err
69	}
70
71	if !b {
72		return fmt.Errorf("value does not match pattern %q", v.Pattern)
73	}
74
75	return nil
76}
77
78type LenValidator struct {
79	Min *int
80	Max *int
81}
82
83func (v LenValidator) Validate(value *string) error {
84	if value == nil || (v.Min == nil && v.Max == nil) {
85		return nil
86	}
87
88	if v.Min != nil && len(*value) < *v.Min {
89		return fmt.Errorf("value cannot be shorter than %d characters", v.Min)
90	}
91
92	if v.Max != nil && len(*value) > *v.Max {
93		return fmt.Errorf("value cannot be longer than %d characters", v.Max)
94	}
95
96	return nil
97}
98
99type RangeValidator struct {
100	Min int
101	Max int
102}
103
104func (v RangeValidator) Validate(value *string) error {
105	if value == nil {
106		return nil
107	}
108
109	intVal, err := strconv.Atoi(*value)
110	if err != nil {
111		return err
112	}
113
114	if intVal < v.Min || intVal > v.Max {
115		return fmt.Errorf("value is out of range [%d..%d]", v.Min, v.Max)
116	}
117
118	return nil
119}
120
121type NumberValidator struct{}
122
123func (v NumberValidator) Validate(value *string) error {
124	if value == nil {
125		return nil
126	}
127
128	_, err := strconv.Atoi(*value)
129
130	return err
131}
132