// Copyright 2013 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package model

import (
	
	
	
	
	
)

const (
	// AlertNameLabel is the name of the label containing the alert's name.
	AlertNameLabel = "alertname"

	// ExportedLabelPrefix is the prefix to prepend to the label names present in
	// exported metrics if a label of the same name is added by the server.
	ExportedLabelPrefix = "exported_"

	// MetricNameLabel is the label name indicating the metric name of a
	// timeseries.
	MetricNameLabel = "__name__"

	// SchemeLabel is the name of the label that holds the scheme on which to
	// scrape a target.
	SchemeLabel = "__scheme__"

	// AddressLabel is the name of the label that holds the address of
	// a scrape target.
	AddressLabel = "__address__"

	// MetricsPathLabel is the name of the label that holds the path on which to
	// scrape a target.
	MetricsPathLabel = "__metrics_path__"

	// ScrapeIntervalLabel is the name of the label that holds the scrape interval
	// used to scrape a target.
	ScrapeIntervalLabel = "__scrape_interval__"

	// ScrapeTimeoutLabel is the name of the label that holds the scrape
	// timeout used to scrape a target.
	ScrapeTimeoutLabel = "__scrape_timeout__"

	// ReservedLabelPrefix is a prefix which is not legal in user-supplied
	// label names.
	ReservedLabelPrefix = "__"

	// MetaLabelPrefix is a prefix for labels that provide meta information.
	// Labels with this prefix are used for intermediate label processing and
	// will not be attached to time series.
	MetaLabelPrefix = "__meta_"

	// TmpLabelPrefix is a prefix for temporary labels as part of relabelling.
	// Labels with this prefix are used for intermediate label processing and
	// will not be attached to time series. This is reserved for use in
	// Prometheus configuration files by users.
	TmpLabelPrefix = "__tmp_"

	// ParamLabelPrefix is a prefix for labels that provide URL parameters
	// used to scrape a target.
	ParamLabelPrefix = "__param_"

	// JobLabel is the label name indicating the job from which a timeseries
	// was scraped.
	JobLabel = "job"

	// InstanceLabel is the label name used for the instance label.
	InstanceLabel = "instance"

	// BucketLabel is used for the label that defines the upper bound of a
	// bucket of a histogram ("le" -> "less or equal").
	BucketLabel = "le"

	// QuantileLabel is used for the label that defines the quantile in a
	// summary.
	QuantileLabel = "quantile"
)

// LabelNameRE is a regular expression matching valid label names. Note that the
// IsValid method of LabelName performs the same check but faster than a match
// with this regular expression.
var LabelNameRE = regexp.MustCompile("^[a-zA-Z_][a-zA-Z0-9_]*$")

// A LabelName is a key for a LabelSet or Metric.  It has a value associated
// therewith.
type LabelName string

// IsValid returns true iff the name matches the pattern of LabelNameRE when
// NameValidationScheme is set to LegacyValidation, or valid UTF-8 if
// NameValidationScheme is set to UTF8Validation.
func ( LabelName) () bool {
	if len() == 0 {
		return false
	}
	switch NameValidationScheme {
	case LegacyValidation:
		return .IsValidLegacy()
	case UTF8Validation:
		return utf8.ValidString(string())
	default:
		panic(fmt.Sprintf("Invalid name validation scheme requested: %d", NameValidationScheme))
	}
}

// IsValidLegacy returns true iff name matches the pattern of LabelNameRE for
// legacy names. It does not use LabelNameRE for the check but a much faster
// hardcoded implementation.
func ( LabelName) () bool {
	if len() == 0 {
		return false
	}
	for ,  := range  {
		// TODO: Apply De Morgan's law. Make sure there are tests for this.
		if !(( >= 'a' &&  <= 'z') || ( >= 'A' &&  <= 'Z') ||  == '_' || ( >= '0' &&  <= '9' &&  > 0)) { //nolint:staticcheck
			return false
		}
	}
	return true
}

// UnmarshalYAML implements the yaml.Unmarshaler interface.
func ( *LabelName) ( func(interface{}) error) error {
	var  string
	if  := (&);  != nil {
		return 
	}
	if !LabelName().IsValid() {
		return fmt.Errorf("%q is not a valid label name", )
	}
	* = LabelName()
	return nil
}

// UnmarshalJSON implements the json.Unmarshaler interface.
func ( *LabelName) ( []byte) error {
	var  string
	if  := json.Unmarshal(, &);  != nil {
		return 
	}
	if !LabelName().IsValid() {
		return fmt.Errorf("%q is not a valid label name", )
	}
	* = LabelName()
	return nil
}

// LabelNames is a sortable LabelName slice. In implements sort.Interface.
type LabelNames []LabelName

func ( LabelNames) () int {
	return len()
}

func ( LabelNames) (,  int) bool {
	return [] < []
}

func ( LabelNames) (,  int) {
	[], [] = [], []
}

func ( LabelNames) () string {
	 := make([]string, 0, len())
	for ,  := range  {
		 = append(, string())
	}
	return strings.Join(, ", ")
}

// A LabelValue is an associated value for a LabelName.
type LabelValue string

// IsValid returns true iff the string is a valid UTF-8.
func ( LabelValue) () bool {
	return utf8.ValidString(string())
}

// LabelValues is a sortable LabelValue slice. It implements sort.Interface.
type LabelValues []LabelValue

func ( LabelValues) () int {
	return len()
}

func ( LabelValues) (,  int) bool {
	return string([]) < string([])
}

func ( LabelValues) (,  int) {
	[], [] = [], []
}

// LabelPair pairs a name with a value.
type LabelPair struct {
	Name  LabelName
	Value LabelValue
}

// LabelPairs is a sortable slice of LabelPair pointers. It implements
// sort.Interface.
type LabelPairs []*LabelPair

func ( LabelPairs) () int {
	return len()
}

func ( LabelPairs) (,  int) bool {
	switch {
	case [].Name > [].Name:
		return false
	case [].Name < [].Name:
		return true
	case [].Value > [].Value:
		return false
	case [].Value < [].Value:
		return true
	default:
		return false
	}
}

func ( LabelPairs) (,  int) {
	[], [] = [], []
}