package cache

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

var (
	cacheHitsTotal = promauto.With(prometheus.DefaultRegisterer).NewCounterVec(prometheus.CounterOpts{
		Name: "cache_hits_total",
		Help: "Количество попаданий в кэш.",
	}, []string{"cache_id"})
	cacheMissesTotal = promauto.With(prometheus.DefaultRegisterer).NewCounterVec(prometheus.CounterOpts{
		Name: "cache_misses_total",
		Help: "Количество пропусков в кэш.",
	}, []string{"cache_id"})
)

type metricsCache struct {
	cache   Cache
	cacheID string
}

// WithMetrics возвращает обертку над кэшем, которая используется для отслеживания количества хитов и промахов в кэше.
// Помимо этого, в функцию WithMetrics передается параметр cacheID, который используется в метке метрик для идентификации конкретного кэша.
//
// Метрики записываются в prometheus.DefaultRegisterer
func WithMetrics(cache Cache, cacheID string) Cache {
	return &metricsCache{
		cacheID: cacheID,
		cache:   cache,
	}
}

func (c *metricsCache) Set(key, value any) error {
	return c.cache.Set(key, value)
}

func (c *metricsCache) Get(key any) (any, error) {
	value, err := c.cache.Get(key)
	if err != nil {
		cacheMissesTotal.WithLabelValues(c.cacheID).Inc()
		return nil, err
	}
	cacheHitsTotal.WithLabelValues(c.cacheID).Inc()
	return value, nil
}

func (c *metricsCache) Remove(key any) error {
	return c.cache.Remove(key)
}