package main

import (
	"log/slog"
	"net/http/httptest"
	"os"
	"strings"
	"testing"

	"github.com/dbledeez/panel/controller/internal/events"
)

func testPromServer() *httpServer {
	h := &httpServer{
		log:        slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{Level: slog.LevelError})),
		bus:        events.New(8),
		registry:   newAgentRegistry(),
		adminToken: "prom-test-token",
		auth:       &auth{log: slog.Default()},
	}
	h.prom = newPromMetrics(h)
	return h
}

func TestMetricsEndpointAuthAndContent(t *testing.T) {
	h := testPromServer()
	// Force a bus drop so the counter is non-zero.
	sub := h.bus.Subscribe(events.Filter{})
	defer sub.Close()
	for i := 0; i < 10; i++ {
		h.bus.Publish(sseStateEvent("x", "d"))
	}
	h.prom.recordScheduleFire("ok")

	handler := h.handler()

	// Loopback: allowed without credentials.
	r := httptest.NewRequest("GET", "http://panel/metrics", nil)
	r.RemoteAddr = "127.0.0.1:5555"
	w := httptest.NewRecorder()
	handler.ServeHTTP(w, r)
	if w.Code != 200 {
		t.Fatalf("loopback /metrics = %d, want 200", w.Code)
	}
	body := w.Body.String()
	for _, want := range []string{
		"panel_bus_dropped_events_total 2",
		"panel_sse_subscribers 0",
		`panel_schedule_fires_total{status="ok"} 1`,
		"go_goroutines",
	} {
		if !strings.Contains(body, want) {
			t.Fatalf("/metrics missing %q\n%.2000s", want, body)
		}
	}

	// Non-loopback without token: denied.
	r = httptest.NewRequest("GET", "http://panel/metrics", nil)
	r.RemoteAddr = "192.168.1.50:5555"
	w = httptest.NewRecorder()
	handler.ServeHTTP(w, r)
	if w.Code != 401 {
		t.Fatalf("remote /metrics without token = %d, want 401", w.Code)
	}

	// Non-loopback with admin token: allowed.
	r = httptest.NewRequest("GET", "http://panel/metrics", nil)
	r.RemoteAddr = "192.168.1.50:5555"
	r.Header.Set("X-Panel-Admin-Token", "prom-test-token")
	w = httptest.NewRecorder()
	handler.ServeHTTP(w, r)
	if w.Code != 200 {
		t.Fatalf("remote /metrics with token = %d, want 200", w.Code)
	}
}
