package o11ymetrics

import (
	"context"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"time"

	log "github.com/sirupsen/logrus"
	"github.com/tidbcloud/observability/o11ymetering/pkg/common/config"
	"github.com/tidbcloud/observability/o11ymetering/pkg/common/constants"
	"github.com/tidbcloud/observability/o11ymetering/pkg/common/models"
	"github.com/tidbcloud/observability/pkg/common/configs"
	o11yConstants "github.com/tidbcloud/observability/pkg/common/constants"
)

type O11yRegionalDataApi struct {
}

func (o *O11yRegionalDataApi) QueryO11yMetricsInstant(ctx context.Context, vendor, region string, o11yClusterID string, start time.Time, query string, env constants.BizEnv) (metricsResp *models.O11yMetricsResponse, err error) {
	method := "GET"
	url := fmt.Sprintf("%s?%s", urlPath(vendor, region, o11yClusterID, env), params(query, start))

	req, err := http.NewRequestWithContext(ctx, method, url, nil)
	if err != nil {
		return nil, err
	}

	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		log.Errorf("query o11y metrics failed, url = %s", url)
		return nil, err
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {

		body, _ := ioutil.ReadAll(resp.Body)
		return nil, fmt.Errorf("http response status %s from metric data server, body: %s", resp.Status, body)
	}

	result := models.O11yMetricsResponse{}
	if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
		return nil, err
	}
	return &result, nil
}

var ProdDomainPostfix = "observability.tidbcloud.com"
var DevDomainPostfix = "observability-dev.pingcap.cloud"
var StagingDomainPostfix = "observability-staging.pingcap.cloud"

func urlPath(vendor, region string, o11yClusterID string, o11yEnv constants.BizEnv) string {
	rsURL := config.GetMeteringConfig().O11yRegionalDataServiceURL
	if len(rsURL) == 0 {
		var domainPostfix string
		switch configs.GetServiceInfo().Env {
		case o11yConstants.EnvDev:
			domainPostfix = DevDomainPostfix
		case o11yConstants.EnvStaging:
			domainPostfix = StagingDomainPostfix
		case o11yConstants.EnvProd:
			domainPostfix = ProdDomainPostfix
		}
		rsURL = fmt.Sprintf("https://www.ds.%s.%s.%s", region, vendor, domainPostfix)
	}
	return fmt.Sprintf("%s/internal/metrics/%s/api/v1/query", rsURL, o11yClusterID)
}

func params(query string, start time.Time) string {
	return fmt.Sprintf("query=%s&time=%d", url.QueryEscape(query), start.Unix())
}
