package tidbautoscaling

import (
	"strconv"
	"time"

	serverlessv1alpha1 "github.com/tidbcloud/aws-shared-provider/apis/serverless/v1alpha1"
	pkgmetrics "github.com/tidbcloud/aws-shared-provider/pkg/metrics"
)

type float64OrNil struct {
	value   float64
	isValid bool
}

type podMetrics map[string][]float64OrNil

func (ta *TidbAutoscaling) query(metrics []serverlessv1alpha1.Metric) (podMetrics, error) {
	base10 := 10
	//nolint:mnd // no need
	result := make(podMetrics, 2000)
	c := len(metrics)
	for i := range metrics {
		v := map[string]string{
			"query": metrics[i].PromSql,
			"start": strconv.FormatInt(time.Now().Unix(), base10),
			"step":  "1m",
		}
		resp, err := ta.o11yQuerier.QueryRangeMetrics(ta.ctx, "/api/v1/query_range", v)
		if err != nil {
			return nil, err
		}

		for _, rlt := range resp.Data.Result {
			if len(rlt.Values) == 0 {
				continue
			}
			value, err := strconv.ParseFloat(rlt.Values[len(rlt.Values)-1][1].(string), 64)
			if err != nil {
				return result, err
			}
			if pod := rlt.Metric[metrics[i].PodLabel]; pod != "" {
				if _, ok := result[pod]; !ok {
					result[pod] = make([]float64OrNil, c)
				}
				result[pod][i] = float64OrNil{value: value, isValid: true}
			}
		}
	}
	pkgmetrics.TidbPodNumGauge.WithLabelValues(ta.tidbPoolNamespace).Set(float64(len(result)))
	return result, nil
}

func (ta *TidbAutoscaling) queryScaleDownCheck(metrics []serverlessv1alpha1.CheckMetric) (map[string]bool, error) {
	result := make(map[string]bool)
	for i := range metrics {
		v := map[string]string{
			"query": metrics[i].PromSql,
			"start": strconv.FormatInt(time.Now().Unix(), 10),
			"step":  "1m",
		}
		resp, err := ta.o11yQuerier.QueryRangeMetrics(ta.ctx, "/api/v1/query_range", v)
		if err != nil {
			return nil, err
		}

		for _, rlt := range resp.Data.Result {
			if token := rlt.Metric[metrics[i].TokenLabel]; token != "" {
				ta.V(2).Info("disable scale down", "token", token, "name", metrics[i].Name)
				result[token] = true
			}
		}
	}
	pkgmetrics.ScaleDownTokenNumGauge.WithLabelValues(ta.tidbPoolNamespace).Set(float64(len(result)))
	return result, nil
}
