// Copyright 2019 Yunion
//
// 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 monitor

import (
	time "time"
)

const (
	ALERT_STATUS_READY       = "ready"
	ALERT_STATUS_DELETE      = "start_delete"
	ALERT_STATUS_DELETE_FAIL = "delete_fail"
	ALERT_STATUS_DELETING    = "deleting"
	ALERT_STATUS_DELETED     = "deleted"

	CommonAlertSystemAlertType  = "system"
	CommonAlertNomalAlertType   = "normal"
	CommonAlertServiceAlertType = "service"

	MonitorComponentType = "default-monitor"
	MonitorComponentPort = 30093
	SubscribAPI          = "subscriptions"
	MonitorDefaultRC     = "30day_only"
	MonitorSubName       = "commonalert"
	MonitorSubDataBase   = "telegraf"

	CommonAlertDefaultRecipient = "commonalert-default"

	DEFAULT_SEND_NOTIFY_CHANNEL = "users"

	METRIC_QUERY_TYPE_NO_DATA     = "nodata_query"
	METRIC_QUERY_NO_DATA_THESHOLD = "nodata"

	CommonAlertLevelNormal    = "normal"
	CommonAlertLevelImportant = "important"
	CommonAlertLevelFatal     = "fatal"
)

type CommonAlertFieldOpt string

const (
	//metirc fields 之间的运算
	CommonAlertFieldOptDivision CommonAlertFieldOpt = "/"
)

var CommonAlertLevels = []string{CommonAlertLevelNormal, CommonAlertLevelImportant, CommonAlertLevelFatal}

type CommonAlertCreateBaseInput struct {
	// 报警连续持续周期数
	AlertDuration int64 `json:"alert_duration"`
	// 通知方式, 比如: email, mobile
	Channel []string `json:"channel"`
	// 通知接受者
	Recipients []string `json:"recipients"`

	RobotIds []string `json:"robot_ids"`

	// 角色 id 或者 name
	Roles []string `json:"roles"`

	// 为 true 时不发送恢复通知（OK）
	DisableNotifyRecovery *bool `json:"disable_notify_recovery"`

	// 静默期
	SilentPeriod string `json:"silent_period"`
	// 报警类型
	AlertType string `json:"alert_type"`

	// Scope Resource
	Scope       string `json:"scope"`
	DomainId    string `json:"domain_id"`
	ProjectId   string `json:"project_id"`
	GetPointStr bool   `json:"get_point_str"`
	MetaName    string `json:"meta_name"`
	Description string `json:"description"`
}

type CommonAlertCreateInput struct {
	CommonMetricInputQuery
	AlertCreateInput
	CommonAlertCreateBaseInput

	// 查询指标周期
	Period string `json:"period"`
}

type CommonMetricInputQuery struct {
	From        string              `json:"from"`
	To          string              `json:"to"`
	Interval    string              `json:"interval"`
	MetricQuery []*CommonAlertQuery `json:"metric_query"`
}

type CommonAlertQuery struct {
	*AlertQuery
	// metric points'value的运算方式
	Reduce string `json:"reduce"`
	// 比较运算符, 比如: >, <, >=, <=, within_range, outside_range
	Comparator string `json:"comparator"`
	// 报警阀值 (用于 gt, lt, eq)
	Threshold float64 `json:"threshold"`
	// 范围参数 (用于 within_range, outside_range)
	ThresholdRange []float64 `json:"threshold_range"`
	// field 运算
	FieldOpt      CommonAlertFieldOpt `json:"field_opt"`
	ConditionType string              `json:"condition_type"`
	// Operator should be chosen from 'and | or'
	Operator string `json:"operator"`
}

// TopQueryInput 用于 top 查询的通用时间段和 top 参数
type TopQueryInput struct {
	// 查询时间段开始时间
	StartTime time.Time `json:"start_time"`
	// 查询时间段结束时间
	EndTime time.Time `json:"end_time"`
	// 返回 top N（默认 5）
	Top *int `json:"top"`
}

type CommonAlertListInput struct {
	AlertListInput
	//V1AlertListInput
	// 报警类型
	AlertType string `json:"alert_type"`
	// 监控指标名称
	Metric string `json:"metric"`

	Level   string   `json:"level"`
	ResType []string `json:"res_type"`
	UsedBy  string   `json:"used_by"`
	Name    string   `json:"name"`
	// Top 查询参数（用于统计报警资源最多的监控策略）
	TopQueryInput
}

type CommonAlertUpdateInput struct {
	CommonMetricInputQuery
	V1AlertUpdateInput

	// 查询指标周期
	Period string `json:"period"`
	// 报警连续持续周期数
	AlertDuration int64 `json:"alert_duration"`
	// 通知方式, 比如: email, mobile
	Channel []string `json:"channel"`
	// 通知接受者
	Recipients []string `json:"recipients"`
	// 为 true 时不发送恢复通知（OK）
	DisableNotifyRecovery *bool `json:"disable_notify_recovery"`
	// 静默期
	SilentPeriod string `json:"silent_period"`
	// systemalert policy may need update through operator
	ForceUpdate bool   `json:"force_update"`
	GetPointStr bool   `json:"get_point_str"`
	MetaName    string `json:"meta_name"`
}

type CommonAlertDetails struct {
	AlertDetails
	Period string `json:"period"`
	// 报警连续持续周期数
	AlertDuration         int64    `json:"alert_duration"`
	Level                 string   `json:"level"`
	NotifierId            string   `json:"notifier_id"`
	Channel               []string `json:"channel"`
	Recipients            []string `json:"recipients"`
	RobotIds              []string `json:"robot_ids"`
	RoleIds               []string `json:"role_ids"`
	DisableNotifyRecovery bool     `json:"disable_notify_recovery"`
	// 静默期
	SilentPeriod string `json:"silent_period"`
	Status       string `json:"status"`
	// 报警类型
	AlertType                string                      `json:"alert_type"`
	CommonAlertMetricDetails []*CommonAlertMetricDetails `json:"common_alert_metric_details"`
}

type CommonAlertMetricDetails struct {
	Operator       string    `json:"operator"`
	Comparator     string    `json:"comparator"`
	Threshold      float64   `json:"threshold"`
	ThresholdRange []float64 `json:"threshold_range"`
	ConditionType  string    `json:"condition_type"`
	ThresholdStr   string    `json:"threshold_str"`
	// metric points'value的运算方式
	Reduce                 string           `json:"reduce"`
	DB                     string           `json:"db"`
	Measurement            string           `json:"measurement"`
	MeasurementDisplayName string           `json:"measurement_display_name"`
	ResType                string           `json:"res_type"`
	Field                  string           `json:"field"`
	Groupby                string           `json:"groupby"`
	Filters                []MetricQueryTag `json:"filters"`
	FieldDescription       MetricFieldDetail
	FieldOpt               string `json:"field_opt"`
	GetPointStr            bool   `json:"get_point_str"`
}
