package metrics

import (
	"context"
	"sync/atomic"
)

const indexSelectionSampleEvery = 100

var indexSelectionCounter uint64

// IndexSelectionInfo contains sanitized fields for index selection metrics.
type IndexSelectionInfo struct {
	Outcome   string
	Rule      string
	IndexType string
	Covering  bool
	OrderBy   bool
	BackTable bool
}

// RecordIndexSelection emits a sampled metric for index selection outcomes.
func RecordIndexSelection(ctx context.Context, info IndexSelectionInfo) {
	state := activeState()
	if state == nil || !state.enabled || state.indexSelect == nil {
		return
	}
	if !shouldSample(indexSelectionSampleEvery) {
		return
	}

	outcome := normalizeLabel(info.Outcome, "unknown")
	rule := normalizeLabel(info.Rule, "none")
	indexType := normalizeLabel(info.IndexType, "unknown")
	labels := labelsFromContext(ctx)

	state.indexSelect.WithLabelValues(
		outcome,
		rule,
		indexType,
		boolLabel(info.Covering),
		boolLabel(info.OrderBy),
		boolLabel(info.BackTable),
		labels.KeyspaceName,
		labels.ClusterID,
	).Inc()
}

func shouldSample(every uint64) bool {
	if every <= 1 {
		return true
	}
	val := atomic.AddUint64(&indexSelectionCounter, 1)
	return val%every == 0
}

func normalizeLabel(value, fallback string) string {
	if value == "" {
		return fallback
	}
	return value
}

func boolLabel(value bool) string {
	if value {
		return "true"
	}
	return "false"
}
