// Package metrics add by blacknc <blacknc@163.com> at 2023/03/03 11:46:59
package metrics

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

var (
	// Endpooint management metrics
	EndpointSaveCounter        *prometheus.CounterVec
	EndpointDeleteCounter      *prometheus.CounterVec
	EndpointDumpCounter        *prometheus.CounterVec
	EndpointGetCounter         *prometheus.CounterVec
	EndpointTestCounter        *prometheus.CounterVec
	EndpointSessionCounter     *prometheus.CounterVec
	EndpointSqlRunCounter      *prometheus.CounterVec
	EndpointOnlineCounter      *prometheus.CounterVec
	EndpointOfflineCounter     *prometheus.CounterVec
	EndpointCodeExampleCounter *prometheus.CounterVec

	// Endpooint exec metrics
	ExecEndpointFailedCounter     *prometheus.CounterVec
	GetEndpointDuration           *prometheus.HistogramVec
	CheckApiKeyPermissionDuration prometheus.Histogram
	ExecutionLinkDuration         *prometheus.HistogramVec

	// Endpoint cache metrics
	CacheHitCounter *prometheus.CounterVec
	CacheSizeGuage  *prometheus.GaugeVec
)

const (
	TpDraftEndpoint   = "draft"
	TpPublishEndpoint = "publish"
)

func endpointMgmtRegister(subsystem string) {
	EndpointSaveCounter = prometheus.NewCounterVec(prometheus.CounterOpts{
		Namespace: namespace,
		Subsystem: subsystem,
		Name:      "endpoint_save_count",
		Help:      "Number of times the endpoint has been saved.",
	}, []string{"code"})

	EndpointDeleteCounter = prometheus.NewCounterVec(prometheus.CounterOpts{
		Namespace: namespace,
		Subsystem: subsystem,
		Name:      "endpoint_delete_count",
		Help:      "Number of times the endpoint has been deleted.",
	}, []string{"code"})

	EndpointDumpCounter = prometheus.NewCounterVec(prometheus.CounterOpts{
		Namespace: namespace,
		Subsystem: subsystem,
		Name:      "endpoint_dump_count",
		Help:      "Number of times the endpoint has been dump.",
	}, []string{"code"})

	EndpointGetCounter = prometheus.NewCounterVec(prometheus.CounterOpts{
		Namespace: namespace,
		Subsystem: subsystem,
		Name:      "endpoint_get_count",
		Help:      "Number of times the endpoint has been geted.",
	}, []string{"code"})

	EndpointTestCounter = prometheus.NewCounterVec(prometheus.CounterOpts{
		Namespace: namespace,
		Subsystem: subsystem,
		Name:      "endpoint_test_count",
		Help:      "Number of times the endpoint has been test.",
	}, []string{"code"})

	EndpointSessionCounter = prometheus.NewCounterVec(prometheus.CounterOpts{
		Namespace: namespace,
		Subsystem: subsystem,
		Name:      "endpoint_session_count",
		Help:      "Number of sessions created by endpoint.",
	}, []string{"code"})

	EndpointSqlRunCounter = prometheus.NewCounterVec(prometheus.CounterOpts{
		Namespace: namespace,
		Subsystem: subsystem,
		Name:      "endpoint_sqlrun_count",
		Help:      "Number of times sql has been executed.",
	}, []string{"code"})

	EndpointOnlineCounter = prometheus.NewCounterVec(prometheus.CounterOpts{
		Namespace: namespace,
		Subsystem: subsystem,
		Name:      "endpoint_online_count",
		Help:      "Number of times endpoint has been online.",
	}, []string{"code"})

	EndpointOfflineCounter = prometheus.NewCounterVec(prometheus.CounterOpts{
		Namespace: namespace,
		Subsystem: subsystem,
		Name:      "endpoint_offline_count",
		Help:      "Number of times endpoint has been offline.",
	}, []string{"code"})

	EndpointCodeExampleCounter = prometheus.NewCounterVec(prometheus.CounterOpts{
		Namespace: namespace,
		Subsystem: subsystem,
		Name:      "endpoint_codeexample_count",
		Help:      "Number of times endpoint get code example.",
	}, []string{"code"})

	prometheus.MustRegister(
		EndpointSaveCounter,
		EndpointDeleteCounter,
		EndpointDumpCounter,
		EndpointGetCounter,
		EndpointTestCounter,
		EndpointSessionCounter,
		EndpointSqlRunCounter,
		EndpointOnlineCounter,
		EndpointOfflineCounter,
		EndpointCodeExampleCounter,
	)
}

func endpointExecRegister(subsystem string) {
	ExecEndpointFailedCounter = prometheus.NewCounterVec(prometheus.CounterOpts{
		Namespace: namespace,
		Subsystem: subsystem,
		Name:      "exec_endpoint_count",
		Help:      "The RPC request count.",
	}, []string{"error"})

	GetEndpointDuration = prometheus.NewHistogramVec(prometheus.HistogramOpts{
		Namespace: namespace,
		Subsystem: subsystem,
		Name:      "get_endpoint_duration",
		Help:      "Get endpoint latencies in second.",
		Buckets:   prometheus.ExponentialBuckets(0.001, 2, 20), // 1ms ~ 524s
	}, []string{"type", "method", "ok"})

	CheckApiKeyPermissionDuration = prometheus.NewHistogram(prometheus.HistogramOpts{
		Namespace: namespace,
		Subsystem: subsystem,
		Name:      "check_apikey_duration",
		Help:      "Check ApiKey permission latencies in second.",
		Buckets:   prometheus.ExponentialBuckets(0.001, 2, 20), // 1ms ~ 524s
	})

	ExecutionLinkDuration = prometheus.NewHistogramVec(prometheus.HistogramOpts{
		Namespace: namespace,
		Subsystem: subsystem,
		Name:      "execution_link_duration",
		Help:      "Execution link latencies in second.",
		Buckets:   prometheus.ExponentialBuckets(0.001, 2, 20), // 1ms ~ 524s
	}, []string{"sence", "action"})

	prometheus.MustRegister(
		ExecEndpointFailedCounter,
		GetEndpointDuration,
		CheckApiKeyPermissionDuration,
		ExecutionLinkDuration,
	)
}

func endpointCacheRegister(subsystem string) {
	CacheHitCounter = prometheus.NewCounterVec(prometheus.CounterOpts{
		Namespace: namespace,
		Subsystem: subsystem,
		Name:      "endpoint_cache_hit_count",
	}, []string{"endpoint_id", "external_app_id", "hit_status"})
	CacheSizeGuage = prometheus.NewGaugeVec(prometheus.GaugeOpts{
		Namespace: namespace,
		Subsystem: subsystem,
		Name:      "endpoint_cache_size_stat",
	}, []string{"external_app_id"})

	prometheus.MustRegister(CacheHitCounter, CacheSizeGuage)
}
