// Package http add by blacknc <blacknc@163.com> at 2023/11/14 15:43:23
package http

import (
	"context"
	"dataservices/commons/config"
	"dataservices/commons/httpclient"
	"encoding/json"
	"fmt"
	"net/url"

	"github.com/tidbcloud/tiinf/monitor/tilog"
)

type MetricOutput struct {
	Status string `json:"status"`
	Data   struct {
		ResultType string          `json:"resultType"`
		Result     json.RawMessage `json:"result"`
	} `json:"data"`
	ErrorType string `json:"errorType"`
	Error     string `json:"error"`
}

func (o *MetricOutput) UnmarshalResult(target any) error {
	return json.Unmarshal(o.Data.Result, target)
}

type QueryOutput struct {
	Metric map[string]any `json:"metric"`
	Value  []any          `json:"value"`
}

func MetricQuery(ctx context.Context, query string, time string) ([]*QueryOutput, error) {
	var (
		urlPrefix = getO11yRegionUrl()
		values    = url.Values{}
	)
	if urlPrefix == "" {
		tilog.Info(ctx, "o11y region metrics url is empty")
		return nil, nil
	}
	values.Add("query", query)
	if time != "" {
		values.Add("time", time)
	}
	requestUrl := fmt.Sprintf("%s/api/v1/query?%s", urlPrefix, values.Encode())

	resp, code, err := httpclient.Get(requestUrl)
	if err != nil {
		return nil, fmt.Errorf("falied to request metrics, url:%s, err:%v", requestUrl, err)
	}
	var output MetricOutput
	err = parseResp(ctx, resp, code, err, &output)
	if err != nil {
		return nil, err
	} else if output.Status != "success" {
		return nil, fmt.Errorf("falied to query metrics, url:%s, response:%v", requestUrl, resp)
	}
	var result []*QueryOutput
	if err := output.UnmarshalResult(&result); err != nil {
		return nil, fmt.Errorf("falied to parse metrics result, url:%s, err:%v", requestUrl, err)
	}
	return result, nil
}

func getO11yRegionUrl() string {
	url := config.Global().O11YRegionMetricUrl
	if url == "" && config.IsLocalMode() {
		url = "http://www.ds.us-west-2.aws.observability-staging.pingcap.cloud/internal/metrics/f98fac90-a0d1-4762-a42a-5a13fe650a09"
	}
	return url
}
