/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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 prometheus

import (
	"context"
	"strconv"
	"strings"
	"sync"
	"time"
)

import (
	"github.com/prometheus/client_golang/prometheus"
)

import (
	"dubbo.apache.org/dubbo-go/v3/common"
	"dubbo.apache.org/dubbo-go/v3/common/constant"
	"dubbo.apache.org/dubbo-go/v3/common/extension"
	"dubbo.apache.org/dubbo-go/v3/common/logger"
	"dubbo.apache.org/dubbo-go/v3/config"
	"dubbo.apache.org/dubbo-go/v3/metrics"
	"dubbo.apache.org/dubbo-go/v3/protocol"
)

const (
	reporterName = "prometheus"
	serviceKey   = constant.SERVICE_KEY
	groupKey     = constant.GROUP_KEY
	versionKey   = constant.VERSION_KEY
	methodKey    = constant.METHOD_KEY
	timeoutKey   = constant.TIMEOUT_KEY

	providerKey = "provider"
	consumerKey = "consumer"

	// to identify the metric's type
	histogramSuffix = "_histogram"
	// to identify the metric's type
	summarySuffix = "_summary"
)

var (
	labelNames       = []string{serviceKey, groupKey, versionKey, methodKey, timeoutKey}
	namespace        = config.GetApplicationConfig().Name
	reporterInstance *PrometheusReporter
	reporterInitOnce sync.Once
)

// should initialize after loading configuration
func init() {
	extension.SetMetricReporter(reporterName, newPrometheusReporter)
}

// PrometheusReporter will collect the data for Prometheus
// if you want to use this feature, you need to initialize your prometheus.
// https://prometheus.io/docs/guides/go-application/
type PrometheusReporter struct {
	// report the consumer-side's summary data
	consumerSummaryVec *prometheus.SummaryVec
	// report the provider-side's summary data
	providerSummaryVec *prometheus.SummaryVec
	// report the provider-side's histogram data
	providerHistogramVec *prometheus.HistogramVec
	// report the consumer-side's histogram data
	consumerHistogramVec *prometheus.HistogramVec
}

// Report reports the duration to Prometheus
// the role in url must be consumer or provider
// or it will be ignored
func (reporter *PrometheusReporter) Report(ctx context.Context, invoker protocol.Invoker, invocation protocol.Invocation, cost time.Duration, res protocol.Result) {
	url := invoker.GetURL()
	var sumVec *prometheus.SummaryVec
	var hisVec *prometheus.HistogramVec
	if isProvider(url) {
		sumVec = reporter.providerSummaryVec
		hisVec = reporter.providerHistogramVec
	} else if isConsumer(url) {
		sumVec = reporter.consumerSummaryVec
		hisVec = reporter.consumerHistogramVec
	} else {
		logger.Warnf("The url belongs neither the consumer nor the provider, "+
			"so the invocation will be ignored. url: %s", url.String())
		return
	}

	labels := prometheus.Labels{
		serviceKey: url.Service(),
		groupKey:   url.GetParam(groupKey, ""),
		versionKey: url.GetParam(versionKey, ""),
		methodKey:  invocation.MethodName(),
		timeoutKey: url.GetParam(timeoutKey, ""),
	}

	costMs := float64(cost.Nanoseconds() / constant.MsToNanoRate)
	sumVec.With(labels).Observe(costMs)
	hisVec.With(labels).Observe(costMs)
}

func newHistogramVec(side string) *prometheus.HistogramVec {
	mc := config.GetMetricConfig()
	return prometheus.NewHistogramVec(
		prometheus.HistogramOpts{
			Namespace: namespace,
			Subsystem: side,
			Name:      serviceKey + histogramSuffix,
			Help:      "This is the dubbo's histogram metrics",
			Buckets:   mc.GetHistogramBucket(),
		},
		labelNames)
}

// whether this url represents the application received the request as server
func isProvider(url *common.URL) bool {
	role := url.GetParam(constant.ROLE_KEY, "")
	return strings.EqualFold(role, strconv.Itoa(common.PROVIDER))
}

// whether this url represents the application sent then request as client
func isConsumer(url *common.URL) bool {
	role := url.GetParam(constant.ROLE_KEY, "")
	return strings.EqualFold(role, strconv.Itoa(common.CONSUMER))
}

// newSummaryVec create SummaryVec, the Namespace is dubbo
// the objectives is from my experience.
func newSummaryVec(side string) *prometheus.SummaryVec {
	return prometheus.NewSummaryVec(
		prometheus.SummaryOpts{
			Namespace: namespace,
			Help:      "This is the dubbo's summary metrics",
			Subsystem: side,
			Name:      serviceKey + summarySuffix,
			Objectives: map[float64]float64{
				0.5:   0.01,
				0.75:  0.01,
				0.90:  0.005,
				0.98:  0.002,
				0.99:  0.001,
				0.999: 0.0001,
			},
		},
		labelNames,
	)
}

// newPrometheusReporter create new prometheusReporter
// it will register the metrics into prometheus
func newPrometheusReporter() metrics.Reporter {
	if reporterInstance == nil {
		reporterInitOnce.Do(func() {
			reporterInstance = &PrometheusReporter{
				consumerSummaryVec: newSummaryVec(consumerKey),
				providerSummaryVec: newSummaryVec(providerKey),

				consumerHistogramVec: newHistogramVec(consumerKey),
				providerHistogramVec: newHistogramVec(providerKey),
			}
			prometheus.MustRegister(reporterInstance.consumerSummaryVec, reporterInstance.providerSummaryVec,
				reporterInstance.consumerHistogramVec, reporterInstance.providerHistogramVec)
		})
	}
	return reporterInstance
}
