1package atc
2
3import (
4	"fmt"
5	"regexp"
6	"strings"
7)
8
9type ConfigWarning struct {
10	Type    string `json:"type"`
11	Message string `json:"message"`
12}
13
14var validIdentifiers = regexp.MustCompile(`^[\p{Ll}\p{Lt}\p{Lm}\p{Lo}][\p{Ll}\p{Lt}\p{Lm}\p{Lo}\d\-.]*$`)
15var startsWithLetter = regexp.MustCompile(`^[^\p{Ll}\p{Lt}\p{Lm}\p{Lo}]`)
16var invalidCharacter = regexp.MustCompile(`([^\p{Ll}\p{Lt}\p{Lm}\p{Lo}\d\-.])`)
17
18func ValidateIdentifier(identifier string, context ...string) *ConfigWarning {
19	if identifier != "" && !validIdentifiers.MatchString(identifier) {
20		var reason string
21		if startsWithLetter.MatchString(identifier) {
22			reason = "must start with a lowercase letter"
23		} else if invalidChar := invalidCharacter.Find([]byte(identifier[1:])); invalidChar != nil {
24			reason = fmt.Sprintf("illegal character '%s'", invalidChar)
25		}
26		return &ConfigWarning{
27			Type:    "invalid_identifier",
28			Message: fmt.Sprintf("%s: %s", strings.Join(context, ""), fmt.Sprintf("'%s' is not a valid identifier: %s", identifier, reason)),
29		}
30	}
31	return nil
32}
33