/******************************************************************************
 * Copyright (c)  2023 PingCAP, Inc.                                          *
 * 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 structs

import (
	"regexp"
	"strconv"

	"github.com/tidbcloud/observability/pkg/common/constants"
)

var (
	// pre compile regexp to improve performance
	re = regexp.MustCompile(constants.RULE_EXPR_REGEXP)
)

type AlertRuleBase struct {
	AlertRuleID string                    `json:"alertRuleID" form:"alertRuleID"`
	Status      constants.AlertRuleStatus `json:"status" form:"status"`
	Threshold   *float64                  `json:"threshold" form:"threshold"`
	For         *int64                    `json:"for" form:"for"`
}

type AlertRuleDetail struct {
	AlertRuleBase
	CanEdit          string  `json:"canEdit"`
	Alert            string  `json:"alert"`
	MonitorTarget    string  `json:"monitorTarget"`
	Operator         string  `json:"operator"`
	DefaultThreshold float64 `json:"defaultThreshold"`
	DefaultFor       float64 `json:"defaultFor"`
	SortID           int     `json:"sortID"`
}

type UpdateAlertRule struct {
	Status       string  `json:"status"`
	Threshold    float64 `json:"threshold" `
	For          string  `json:"for"`
	OldStatus    string  `json:"oldStatus"`
	OldFor       string  `json:"oldFor"`
	OldThreshold float64 `json:"oldThreshold"`
	AlertName    string  `json:"alertName"`
}

type AlertRuleGroup struct {
	Name  string            `json:"name"`
	Rules []AlertRuleDetail `json:"rules"`
}

type OverLayAlertRuleEXPR struct {
	Operator string
	Expr     string
	Value    float64
}

func GenerateOverLayAlertRuleEXPR(expr string) OverLayAlertRuleEXPR {
	res := re.FindStringSubmatchIndex(expr)
	var overlayEXPR OverLayAlertRuleEXPR
	if len(res) > 2 {
		overlayEXPR.Value, _ = strconv.ParseFloat(expr[res[len(res)-2]:res[len(res)-1]], 64)
		overlayEXPR.Operator = expr[res[len(res)-4]:res[len(res)-3]]
		overlayEXPR.Expr = expr[:res[len(res)-4]]
	}
	return overlayEXPR
}

func (g AlertRuleGroup) Len() int           { return len(g.Rules) }
func (g AlertRuleGroup) Swap(i, j int)      { g.Rules[i], g.Rules[j] = g.Rules[j], g.Rules[i] }
func (g AlertRuleGroup) Less(i, j int) bool { return g.Rules[i].SortID < g.Rules[j].SortID }
