// 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 (
	
	
	
)

type AlertStatus string

const (
	AlertFiring   AlertStatus = "firing"
	AlertResolved AlertStatus = "resolved"
)

// Alert is a generic representation of an alert in the Prometheus eco-system.
type Alert struct {
	// Label value pairs for purpose of aggregation, matching, and disposition
	// dispatching. This must minimally include an "alertname" label.
	Labels LabelSet `json:"labels"`

	// Extra key/value information which does not define alert identity.
	Annotations LabelSet `json:"annotations"`

	// The known time range for this alert. Both ends are optional.
	StartsAt     time.Time `json:"startsAt,omitempty"`
	EndsAt       time.Time `json:"endsAt,omitempty"`
	GeneratorURL string    `json:"generatorURL"`
}

// Name returns the name of the alert. It is equivalent to the "alertname" label.
func ( *Alert) () string {
	return string(.Labels[AlertNameLabel])
}

// Fingerprint returns a unique hash for the alert. It is equivalent to
// the fingerprint of the alert's label set.
func ( *Alert) () Fingerprint {
	return .Labels.Fingerprint()
}

func ( *Alert) () string {
	 := fmt.Sprintf("%s[%s]", .Name(), .Fingerprint().String()[:7])
	if .Resolved() {
		return  + "[resolved]"
	}
	return  + "[active]"
}

// Resolved returns true iff the activity interval ended in the past.
func ( *Alert) () bool {
	return .ResolvedAt(time.Now())
}

// ResolvedAt returns true iff the activity interval ended before
// the given timestamp.
func ( *Alert) ( time.Time) bool {
	if .EndsAt.IsZero() {
		return false
	}
	return !.EndsAt.After()
}

// Status returns the status of the alert.
func ( *Alert) () AlertStatus {
	return .StatusAt(time.Now())
}

// StatusAt returns the status of the alert at the given timestamp.
func ( *Alert) ( time.Time) AlertStatus {
	if .ResolvedAt() {
		return AlertResolved
	}
	return AlertFiring
}

// Validate checks whether the alert data is inconsistent.
func ( *Alert) () error {
	if .StartsAt.IsZero() {
		return errors.New("start time missing")
	}
	if !.EndsAt.IsZero() && .EndsAt.Before(.StartsAt) {
		return errors.New("start time must be before end time")
	}
	if  := .Labels.Validate();  != nil {
		return fmt.Errorf("invalid label set: %w", )
	}
	if len(.Labels) == 0 {
		return errors.New("at least one label pair required")
	}
	if  := .Annotations.Validate();  != nil {
		return fmt.Errorf("invalid annotations: %w", )
	}
	return nil
}

// Alert is a list of alerts that can be sorted in chronological order.
type Alerts []*Alert

func ( Alerts) () int      { return len() }
func ( Alerts) (,  int) { [], [] = [], [] }

func ( Alerts) (,  int) bool {
	if [].StartsAt.Before([].StartsAt) {
		return true
	}
	if [].EndsAt.Before([].EndsAt) {
		return true
	}
	return [].Fingerprint() < [].Fingerprint()
}

// HasFiring returns true iff one of the alerts is not resolved.
func ( Alerts) () bool {
	for ,  := range  {
		if !.Resolved() {
			return true
		}
	}
	return false
}

// HasFiringAt returns true iff one of the alerts is not resolved
// at the time ts.
func ( Alerts) ( time.Time) bool {
	for ,  := range  {
		if !.ResolvedAt() {
			return true
		}
	}
	return false
}

// Status returns StatusFiring iff at least one of the alerts is firing.
func ( Alerts) () AlertStatus {
	if .HasFiring() {
		return AlertFiring
	}
	return AlertResolved
}

// StatusAt returns StatusFiring iff at least one of the alerts is firing
// at the time ts.
func ( Alerts) ( time.Time) AlertStatus {
	if .HasFiringAt() {
		return AlertFiring
	}
	return AlertResolved
}