package metrics

import (
	"github.com/prometheus/client_golang/prometheus"
	"sigs.k8s.io/controller-runtime/pkg/metrics"
)

const (
	tidbmanagerComponent = "tidbmanager"

	AssignTidbHistogramName  = "assignTidbHistogram"
	ActivatorHistogramName   = "activatorHistogram"
	ReplaceTidbHistogramName = "replaceTidbHistogram"
)

var (
	AssignTidbHistogram = prometheus.NewHistogramVec(
		prometheus.HistogramOpts{
			Subsystem: tidbmanagerComponent,
			Name:      "assign_tidb_seconds",
			Help:      "Histogram of assign tidb",
		},
		[]string{"token", "stage", "pool_ns"},
	)

	ActivatorHistogram = prometheus.NewHistogramVec(
		prometheus.HistogramOpts{
			Subsystem: tidbmanagerComponent,
			Name:      "activate_seconds",
			Help:      "Histogram of activator tidb",
		},
		[]string{"token", "pool_ns", "rlt"},
	)

	ActivatorCounter = prometheus.NewCounterVec(
		prometheus.CounterOpts{
			Subsystem: tidbmanagerComponent,
			Name:      "activate_total",
			Help:      "Counter of activator tidb",
		},
		[]string{"pool_ns"},
	)

	AssignTidbScoreHistogram = prometheus.NewHistogramVec(
		prometheus.HistogramOpts{
			Subsystem: tidbmanagerComponent,
			Name:      "assign_tidb_score",
			Help:      "Histogram of assign tidb score",
			Buckets:   []float64{-100, -50, 0, 20, 40, 60, 80},
		},
		[]string{"pool_ns"},
	)

	WatchLoopCounter = prometheus.NewCounterVec(
		prometheus.CounterOpts{
			Subsystem: tidbmanagerComponent,
			Name:      "watch_loop_total",
			Help:      "Counter of etcd watch loop",
		},
		[]string{"pool_ns"},
	)

	EventCounter = prometheus.NewCounterVec(
		prometheus.CounterOpts{
			Subsystem: tidbmanagerComponent,
			Name:      "event_total",
			Help:      "Counter of etcd event",
		},
		[]string{"event_type", "key_type", "pool_ns"},
	)

	RemovePodQueueLenGauge = prometheus.NewGaugeVec(
		prometheus.GaugeOpts{
			Subsystem: tidbmanagerComponent,
			Name:      "remove_pod_queue_len",
			Help:      "Gauge of removePod queue length",
		},
		[]string{"capacity", "pool_ns"},
	)

	RemovePodQueueOverflowCounter = prometheus.NewCounterVec(
		prometheus.CounterOpts{
			Subsystem: tidbmanagerComponent,
			Name:      "remove_pod_queue_overflow_total",
			Help:      "Counter of removePod queue overflow",
		},
		[]string{"pool_ns"},
	)

	RemovePodCounter = prometheus.NewCounterVec(
		prometheus.CounterOpts{
			Subsystem: tidbmanagerComponent,
			Name:      "remove_pod_total",
			Help:      "Counter of removePod queue overflow",
		},
		[]string{"pool_ns"},
	)

	CacheSizeGauge = prometheus.NewGaugeVec(
		prometheus.GaugeOpts{
			Subsystem: tidbmanagerComponent,
			Name:      "cache_size",
			Help:      "Gauge of free/assign_token/assign_endpoint cache size",
		},
		[]string{"type", "pool_ns"},
	)

	ReplaceTidbHistogram = prometheus.NewHistogramVec(
		prometheus.HistogramOpts{
			Subsystem: tidbmanagerComponent,
			Name:      "replace_tidb_seconds",
			Help:      "Histogram of replace tidb",
		},
		[]string{"token", "stage", "pool_ns"},
	)

	ResumeEtcdTokenCounter = prometheus.NewCounterVec(
		prometheus.CounterOpts{
			Subsystem: tidbmanagerComponent,
			Name:      "resume_etcd_token_total",
			Help:      "Counter of resume etcd token for empty tidbpool",
		},
		[]string{"pool_ns"},
	)

	StandbyQuarantinedPodsGauge = prometheus.NewGaugeVec(
		prometheus.GaugeOpts{
			Subsystem: tidbmanagerComponent,
			Name:      "standby_quarantined_pods",
			Help:      "Number of TiDB pods quarantined while waiting to return to standby",
		},
		[]string{"pool_ns"},
	)

	ActivateTerminatingCounter = prometheus.NewCounterVec(
		prometheus.CounterOpts{
			Subsystem: tidbmanagerComponent,
			Name:      "activate_terminating_total",
			Help:      "Counter of TiDB activation attempts rejected because the pod is terminating",
		},
		[]string{"pool_ns"},
	)

	StandbyCheckCompletedCounter = prometheus.NewCounterVec(
		prometheus.CounterOpts{
			Subsystem: tidbmanagerComponent,
			Name:      "standby_check_completed_total",
			Help:      "Counter of completed TiDB standby checks",
		},
		[]string{"pool_ns", "result"},
	)
)

func init() {
	// Register custom metrics with the global prometheus registry
	metrics.Registry.MustRegister(AssignTidbHistogram)
	metrics.Registry.MustRegister(ActivatorHistogram)
	metrics.Registry.MustRegister(ActivatorCounter)
	metrics.Registry.MustRegister(WatchLoopCounter)
	metrics.Registry.MustRegister(EventCounter)
	metrics.Registry.MustRegister(RemovePodQueueLenGauge)
	metrics.Registry.MustRegister(RemovePodQueueOverflowCounter)
	metrics.Registry.MustRegister(RemovePodCounter)
	metrics.Registry.MustRegister(CacheSizeGauge)
	metrics.Registry.MustRegister(ReplaceTidbHistogram)
	metrics.Registry.MustRegister(StandbyQuarantinedPodsGauge)
	metrics.Registry.MustRegister(ActivateTerminatingCounter)
	metrics.Registry.MustRegister(StandbyCheckCompletedCounter)

	Reclaimer.AddHistogramVec(AssignTidbHistogramName, "token", AssignTidbHistogram)
	Reclaimer.AddHistogramVec(ActivatorHistogramName, "token", ActivatorHistogram)
	Reclaimer.AddHistogramVec(ReplaceTidbHistogramName, "token", ReplaceTidbHistogram)
}
