package datapipeline

import "github.com/prometheus/client_golang/prometheus"

const (
	ns        = "dataflow"
	subsystem = "data_pipeline"

	TenantLabel     = "tenant"
	ClusterIDLabel  = "cluster_id"
	PipelineIDLabel = "pipeline_id"
)

var commonIDLabels = []string{TenantLabel, ClusterIDLabel, PipelineIDLabel}

var (
	StatusCount = prometheus.NewDesc(
		prometheus.BuildFQName(ns, subsystem, "status_count"),
		"Current data pipeline count grouped by tenant, cluster, and status. "+
			"Completed pipelines are not counted: they are terminal, accumulate "+
			"forever, and nothing about them is actionable.",
		[]string{TenantLabel, ClusterIDLabel, "status"},
		nil,
	)

	StatusDurationSeconds = prometheus.NewDesc(
		prometheus.BuildFQName(ns, subsystem, "status_duration_seconds"),
		"How long a data pipeline has stayed in its current status, "+
			"approximated by updated_at and falling back to created_at.",
		append(commonIDLabels, "status"),
		nil,
	)

	RecentFail = prometheus.NewDesc(
		prometheus.BuildFQName(ns, subsystem, "recent_fail"),
		"Seconds since a data pipeline failed, emitted only within a recent "+
			"lookback window so that each failure is alertable as an event "+
			"rather than as a level that stays high until someone cleans up.",
		append(commonIDLabels, "error_code"),
		nil,
	)

	// ObservationStalenessSeconds is the metric that catches the failure the
	// others cannot: the observer itself being broken. Every other signal here
	// is derived from what the observer last wrote, so a stopped or failing
	// observer leaves a pipeline looking exactly as healthy as it did at the
	// moment we lost sight of it.
	ObservationStalenessSeconds = prometheus.NewDesc(
		prometheus.BuildFQName(ns, subsystem, "observation_staleness_seconds"),
		"Seconds since the last fully successful observation of a data "+
			"pipeline's children, measured from creation when none has ever "+
			"succeeded. Only reported for the statuses the observer polls.",
		append(commonIDLabels, "status"),
		nil,
	)

	// LatencySeconds is absent rather than zero when either side of the
	// subtraction is unknown, because a pipeline that has not reported a
	// checkpoint yet is not a pipeline with no lag.
	LatencySeconds = prometheus.NewDesc(
		prometheus.BuildFQName(ns, subsystem, "latency_seconds"),
		"End-to-end delivery lag of a data pipeline: the gap between the "+
			"changefeed checkpoint and the destination's resolved position. "+
			"Reported only once both positions are known.",
		commonIDLabels,
		nil,
	)

	ChildError = prometheus.NewDesc(
		prometheus.BuildFQName(ns, subsystem, "child_error"),
		"Set to 1 for each child resource (export, changefeed, lake) reporting "+
			"an error under a pipeline that is still supposed to be running. "+
			"This is what fires when a pipeline's own status still reads "+
			"healthy but one of the three things it orchestrates has stopped.",
		append(commonIDLabels, "child"),
		nil,
	)
)
