package engine

import (
	"time"

	"git.frostfs.info/TrueCloudLab/frostfs-node/internal/metrics"
	"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard/mode"
)

type (
	MetricRegister    = metrics.EngineMetrics
	GCMetrics         = metrics.GCMetrics
	WriteCacheMetrics = metrics.WriteCacheMetrics
	NullBool          = metrics.NullBool
)

func elapsed(method string, addFunc func(method string, d time.Duration)) func() {
	t := time.Now()

	return func() {
		addFunc(method, time.Since(t))
	}
}

type gcMetrics struct {
	storage metrics.GCMetrics
	shardID string
}

func (m *gcMetrics) SetShardID(id string) {
	m.shardID = id
}

func (m *gcMetrics) AddRunDuration(d time.Duration, success bool) {
	m.storage.AddRunDuration(m.shardID, d, success)
}

func (m *gcMetrics) AddDeletedCount(deleted, failed uint64) {
	m.storage.AddDeletedCount(m.shardID, deleted, failed)
}

func (m *gcMetrics) AddExpiredObjectCollectionDuration(d time.Duration, success bool, objectType string) {
	m.storage.AddExpiredObjectCollectionDuration(m.shardID, d, success, objectType)
}

func (m *gcMetrics) AddInhumedObjectCount(count uint64, objectType string) {
	m.storage.AddInhumedObjectCount(m.shardID, count, objectType)
}

type (
	noopMetrics           struct{}
	noopWriteCacheMetrics struct{}
	noopGCMetrics         struct{}
)

var (
	_ MetricRegister    = noopMetrics{}
	_ WriteCacheMetrics = noopWriteCacheMetrics{}
	_ GCMetrics         = noopGCMetrics{}
)

func (noopMetrics) AddMethodDuration(string, time.Duration)                  {}
func (noopMetrics) SetObjectCounter(string, string, uint64)                  {}
func (noopMetrics) AddToObjectCounter(string, string, int)                   {}
func (noopMetrics) SetMode(string, mode.Mode)                                {}
func (noopMetrics) AddToContainerSize(string, int64)                         {}
func (noopMetrics) DeleteContainerSize(string)                               {}
func (noopMetrics) DeleteContainerCount(string)                              {}
func (noopMetrics) AddToPayloadCounter(string, int64)                        {}
func (noopMetrics) IncErrorCounter(string)                                   {}
func (noopMetrics) ClearErrorCounter(string)                                 {}
func (noopMetrics) DeleteShardMetrics(string)                                {}
func (noopMetrics) SetContainerObjectCounter(string, string, string, uint64) {}
func (noopMetrics) IncContainerObjectCounter(string, string, string)         {}
func (noopMetrics) SubContainerObjectCounter(string, string, string, uint64) {}
func (noopMetrics) IncRefillObjectsCount(string, string, int, bool)          {}
func (noopMetrics) SetRefillPercent(string, string, uint32)                  {}
func (noopMetrics) SetRefillStatus(string, string, string)                   {}
func (noopMetrics) SetEvacuationInProgress(string, bool)                     {}
func (noopMetrics) WriteCache() WriteCacheMetrics                            { return noopWriteCacheMetrics{} }
func (noopMetrics) GC() GCMetrics                                            { return noopGCMetrics{} }

func (noopWriteCacheMetrics) AddMethodDuration(string, string, string, string, bool, time.Duration) {}
func (noopWriteCacheMetrics) SetActualCount(string, string, string, uint64)                         {}
func (noopWriteCacheMetrics) SetEstimateSize(string, string, string, uint64)                        {}
func (noopWriteCacheMetrics) SetMode(string, string)                                                {}
func (noopWriteCacheMetrics) IncOperationCounter(string, string, string, string, metrics.NullBool)  {}
func (noopWriteCacheMetrics) Close(string, string)                                                  {}

func (noopGCMetrics) AddRunDuration(string, time.Duration, bool)                             {}
func (noopGCMetrics) AddDeletedCount(string, uint64, uint64)                                 {}
func (noopGCMetrics) AddExpiredObjectCollectionDuration(string, time.Duration, bool, string) {}
func (noopGCMetrics) AddInhumedObjectCount(string, uint64, string)                           {}