package metrics

import (
	"strconv"
	"time"

	"git.frostfs.info/TrueCloudLab/frostfs-observability/metrics"
	"github.com/prometheus/client_golang/prometheus"
)

type TreeMetricsRegister interface {
	AddReplicateTaskDuration(time.Duration, bool)
	AddReplicateWaitDuration(time.Duration, bool)
	AddSyncDuration(time.Duration, bool)
}

type treeServiceMetrics struct {
	replicateTaskDuration *prometheus.HistogramVec
	replicateWaitDuration *prometheus.HistogramVec
	syncOpDuration        *prometheus.HistogramVec
}

var _ TreeMetricsRegister = (*treeServiceMetrics)(nil)

func newTreeServiceMetrics() *treeServiceMetrics {
	return &treeServiceMetrics{
		replicateTaskDuration: metrics.NewHistogramVec(prometheus.HistogramOpts{
			Namespace: namespace,
			Subsystem: treeServiceSubsystem,
			Name:      "replicate_task_duration_seconds",
			Help:      "Duration of individual replication tasks executed as part of replication loops",
		}, []string{successLabel}),
		replicateWaitDuration: metrics.NewHistogramVec(prometheus.HistogramOpts{
			Namespace: namespace,
			Subsystem: treeServiceSubsystem,
			Name:      "replicate_wait_duration_seconds",
			Help:      "Duration of overall waiting time for replication loops",
		}, []string{successLabel}),
		syncOpDuration: metrics.NewHistogramVec(prometheus.HistogramOpts{
			Namespace: namespace,
			Subsystem: treeServiceSubsystem,
			Name:      "sync_duration_seconds",
			Help:      "Duration of synchronization operations",
		}, []string{successLabel}),
	}
}

func (m *treeServiceMetrics) AddReplicateTaskDuration(d time.Duration, success bool) {
	m.replicateTaskDuration.With(prometheus.Labels{
		successLabel: strconv.FormatBool(success),
	}).Observe(d.Seconds())
}

func (m *treeServiceMetrics) AddReplicateWaitDuration(d time.Duration, success bool) {
	m.replicateWaitDuration.With(prometheus.Labels{
		successLabel: strconv.FormatBool(success),
	}).Observe(d.Seconds())
}

func (m *treeServiceMetrics) AddSyncDuration(d time.Duration, success bool) {
	m.syncOpDuration.With(prometheus.Labels{
		successLabel: strconv.FormatBool(success),
	}).Observe(d.Seconds())
}