package middleware

import (
	"net/http"
	"net/http/httptest"
	"testing"

	"github.com/gin-gonic/gin"
	"github.com/stretchr/testify/assert"
)

// Note: Metrics middleware uses prometheus promauto which registers metrics globally.
// These tests verify the middleware behavior without asserting on metric values
// since prometheus registry is global and complex to reset between tests.

func TestPrometheusMiddleware_CompletesRequest(t *testing.T) {
	gin.SetMode(gin.TestMode)
	r := gin.New()
	r.Use(PrometheusMiddleware())
	r.GET("/test", func(c *gin.Context) {
		c.String(http.StatusOK, "ok")
	})

	req := httptest.NewRequest("GET", "/test", nil)
	w := httptest.NewRecorder()
	r.ServeHTTP(w, req)

	assert.Equal(t, http.StatusOK, w.Code)
	assert.Equal(t, "ok", w.Body.String())
}

func TestPrometheusMiddleware_HandlesErrors(t *testing.T) {
	gin.SetMode(gin.TestMode)
	r := gin.New()
	r.Use(PrometheusMiddleware())
	r.GET("/error", func(c *gin.Context) {
		c.String(http.StatusInternalServerError, "error")
	})

	req := httptest.NewRequest("GET", "/error", nil)
	w := httptest.NewRecorder()
	r.ServeHTTP(w, req)

	assert.Equal(t, http.StatusInternalServerError, w.Code)
}

func TestPrometheusMiddleware_HandlesPanic(t *testing.T) {
	gin.SetMode(gin.TestMode)
	r := gin.New()
	r.Use(gin.Recovery()) // Recovery must come before Prometheus
	r.Use(PrometheusMiddleware())
	r.GET("/panic", func(c *gin.Context) {
		panic("test panic")
	})

	req := httptest.NewRequest("GET", "/panic", nil)
	w := httptest.NewRecorder()
	r.ServeHTTP(w, req)

	// With recovery middleware, should return 500 instead of crashing
	assert.Equal(t, http.StatusInternalServerError, w.Code)
}

func TestRecordEventDropped_DoesNotPanic(t *testing.T) {
	assert.NotPanics(t, func() {
		RecordEventDropped("record_created")
	})
}

func TestUpdateEventBusQueueUtilization_DoesNotPanic(t *testing.T) {
	assert.NotPanics(t, func() {
		UpdateEventBusQueueUtilization(0.5)
	})
}
