package prometheus

import (
	"time"

	"github.com/prometheus/client_golang/prometheus"
	log "github.com/sirupsen/logrus"
)

var (
	PromVulnCount = prometheus.NewGaugeVec(
		prometheus.GaugeOpts{
			Name: "labeller_cluster_vulnerabilities_count",
			Help: "Number of vulnerabilities in the cluster, labeled by severity",
		},
		[]string{
			"severity",
		},
	)

	PromVulnerableImages = prometheus.NewGauge(
		prometheus.GaugeOpts{
			Name: "labeller_vulnerable_images",
			Help: "Total number of unique vulnerable images running",
		},
	)

	PromLabellerErrorsTotal = prometheus.NewCounter(
		prometheus.CounterOpts{
			Name: "labeller_errors_total",
			Help: "Number of errors generated by the labeller",
		},
	)

	PromPodEventsTotal = prometheus.NewCounterVec(
		prometheus.CounterOpts{
			Name: "labeller_pod_events_total",
			Help: "Total number of pods events, per namespace",
		},
		[]string{
			"event",
			"namespace",
		},
	)

	PromImageManifestVulnEventsTotal = prometheus.NewCounterVec(
		prometheus.CounterOpts{
			Name: "labeller_image_manifest_vuln_events_total",
			Help: "Total number of ImageManifestVuln events, per namespace",
		},
		[]string{
			"event",
			"namespace",
		},
	)

	PromQueueSize = prometheus.NewGauge(
		prometheus.GaugeOpts{
			Name: "labeller_queue_size",
			Help: "Number of items in the labeller's queue to process",
		},
	)

	PromSecscanRequestsTotal = prometheus.NewCounterVec(
		prometheus.CounterOpts{
			Name: "labeller_secscan_requests_total",
			Help: "Number of requests made to external secscan services, per host",
		},
		[]string{
			"host",
		},
	)

	PromSecscanRequestsDurationSeconds = prometheus.NewHistogramVec(
		prometheus.HistogramOpts{
			Name: "labeller_secscan_requests_duration_seconds",
			Help: "Time it takes fto sync security information from secscan server, in seconds",
		},
		[]string{
			"host",
		},
	)

	PromReconciliationDurationSeconds = prometheus.NewHistogram(
		prometheus.HistogramOpts{
			Name: "labeller_reconciliation_duration_seconds",
			Help: "Time it takes for the operator's reconciliation, in seconds",
		},
	)
)

func ObserveReconciliationDuration() func() {
	start := time.Now()
	return func() {
		PromReconciliationDurationSeconds.Observe(time.Since(start).Seconds())
	}
}

func ObserveSecscanRequestDuration(host string) func() {
	start := time.Now()
	return func() {
		PromSecscanRequestsDurationSeconds.WithLabelValues(host).Observe(time.Since(start).Seconds())
	}
}

func init() {
	prometheus.MustRegister(PromVulnCount)
	prometheus.MustRegister(PromVulnerableImages)
	prometheus.MustRegister(PromLabellerErrorsTotal)
	prometheus.MustRegister(PromPodEventsTotal)
	prometheus.MustRegister(PromImageManifestVulnEventsTotal)
	prometheus.MustRegister(PromQueueSize)
	prometheus.MustRegister(PromSecscanRequestsTotal)
	prometheus.MustRegister(PromSecscanRequestsDurationSeconds)
	prometheus.MustRegister(PromReconciliationDurationSeconds)

	log.Info("Registered prometheus metrics")
}
