package query

import (
	"sync"

	"github.com/prometheus/client_golang/prometheus"
)

var (
	olapQueriesTotal = prometheus.NewCounterVec(prometheus.CounterOpts{
		Namespace: "olap",
		Name:      "queries_total",
		Help:      "OLAP queries that reached a terminal state, by github user.",
	}, []string{"github_username", "status", "dataset", "region"})

	olapScannedBytesTotal = prometheus.NewCounterVec(prometheus.CounterOpts{
		Namespace: "olap",
		Name:      "scanned_bytes_total",
		Help:      "Athena data scanned bytes for terminal OLAP queries, by github user.",
	}, []string{"github_username", "status", "dataset", "region"})

	olapEngineExecutionSeconds = prometheus.NewCounterVec(prometheus.CounterOpts{
		Namespace: "olap",
		Name:      "engine_execution_seconds_total",
		Help:      "Athena engine execution time (seconds) for terminal OLAP queries, by github user.",
	}, []string{"github_username", "status", "dataset", "region"})

	olapQueriesSubmittedTotal = prometheus.NewCounterVec(prometheus.CounterOpts{
		Namespace: "olap",
		Name:      "queries_submitted_total",
		Help:      "OLAP queries submitted, by github user.",
	}, []string{"github_username", "dataset", "region"})

	metricsOnce sync.Once
)

// InitMetrics registers OLAP Prometheus metrics. Idempotent.
func InitMetrics() {
	metricsOnce.Do(func() {
		prometheus.MustRegister(
			olapQueriesTotal,
			olapScannedBytesTotal,
			olapEngineExecutionSeconds,
			olapQueriesSubmittedTotal,
		)
	})
}

func metricGitHubUsername(name string) string {
	if name == "" {
		return "unknown"
	}
	return name
}

func recordOlapSubmitted(job *Job) {
	if job == nil {
		return
	}
	InitMetrics()
	olapQueriesSubmittedTotal.WithLabelValues(
		metricGitHubUsername(job.GitHubUsername),
		firstNonEmpty(job.Dataset, DatasetRaw),
		job.Region,
	).Inc()
}

func recordOlapFinished(job *Job, st *ExecutionStatus) {
	if job == nil || st == nil {
		return
	}
	InitMetrics()
	user := metricGitHubUsername(job.GitHubUsername)
	dataset := firstNonEmpty(job.Dataset, DatasetRaw)
	status := st.Status
	if status == "" {
		status = "unknown"
	}
	labels := []string{user, status, dataset, job.Region}
	olapQueriesTotal.WithLabelValues(labels...).Inc()
	if st.ScannedBytes > 0 {
		olapScannedBytesTotal.WithLabelValues(labels...).Add(float64(st.ScannedBytes))
	}
	if st.EngineExecutionTimeMillis > 0 {
		olapEngineExecutionSeconds.WithLabelValues(labels...).Add(float64(st.EngineExecutionTimeMillis) / 1000.0)
	}
}
