package prometheus

import (
	// Hybrid instrumentation rationale: direct client_golang instrumentation
	// lives in app/webrtc/metrics.go (hot-path counters and histograms);
	// this file owns the snapshot-style gauges. See the design doc at
	// docs/design/2026-05-03-datarhei-dragon-fork-webrtc-prometheus-metrics-design.md.
	"github.com/prometheus/client_golang/prometheus"
)

// WebRTCStats is a point-in-time snapshot of the WebRTC subsystem state.
// Populated by Handler.Stats() in app/webrtc and consumed by the collector
// at scrape time.
type WebRTCStats struct {
	StreamCount   int
	PeersByStream map[string]int
	UDPPortsInUse int
}

// WebRTCStatsSource is implemented by app/webrtc.Handler (via its Stats()
// method). The interface lives here so prometheus/ does not import app/webrtc,
// keeping the dependency arrow one-directional.
type WebRTCStatsSource interface {
	Stats() WebRTCStats
}

type webrtcCollector struct {
	core   string
	source WebRTCStatsSource

	activeStreamsDesc  *prometheus.Desc
	activePeersDesc   *prometheus.Desc
	udpPortsInUseDesc *prometheus.Desc
}

// NewWebRTCCollector returns a prometheus.Collector that emits three gauge
// metrics at scrape time by calling source.Stats(). Register it with the
// shared Metrics registry before the /metrics endpoint starts serving.
func NewWebRTCCollector(core string, source WebRTCStatsSource) prometheus.Collector {
	cl := prometheus.Labels{"core": core}
	return &webrtcCollector{
		core:   core,
		source: source,
		activeStreamsDesc: prometheus.NewDesc(
			"dragonfork_webrtc_active_streams",
			"Streams currently registered (processes with webrtc.enabled=true running).",
			nil, cl,
		),
		activePeersDesc: prometheus.NewDesc(
			"dragonfork_webrtc_active_peers",
			"Currently subscribed WHEP peers per stream.",
			[]string{"stream_id"}, cl,
		),
		udpPortsInUseDesc: prometheus.NewDesc(
			"dragonfork_webrtc_udp_ports_in_use",
			"UDP ports currently allocated (2 per active stream).",
			nil, cl,
		),
	}
}

func (c *webrtcCollector) Describe(ch chan<- *prometheus.Desc) {
	ch <- c.activeStreamsDesc
	ch <- c.activePeersDesc
	ch <- c.udpPortsInUseDesc
}

func (c *webrtcCollector) Collect(ch chan<- prometheus.Metric) {
	stats := c.source.Stats()
	ch <- prometheus.MustNewConstMetric(c.activeStreamsDesc, prometheus.GaugeValue, float64(stats.StreamCount))
	ch <- prometheus.MustNewConstMetric(c.udpPortsInUseDesc, prometheus.GaugeValue, float64(stats.UDPPortsInUse))
	for streamID, count := range stats.PeersByStream {
		ch <- prometheus.MustNewConstMetric(c.activePeersDesc, prometheus.GaugeValue, float64(count), streamID)
	}
}
