package handlers

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

	"github.com/gin-gonic/gin"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
	"veza-backend-api/internal/metrics"
)

func TestPrometheusMetricsEndpoint(t *testing.T) {
	gin.SetMode(gin.TestMode)
	router := gin.New()
	router.GET("/metrics", PrometheusMetrics())

	// Enregistrer quelques erreurs pour avoir des métriques à exposer
	metrics.RecordErrorPrometheus(1000, 401)
	metrics.RecordErrorPrometheus(2000, 400)

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

	assert.Equal(t, http.StatusOK, w.Code)
	
	body := w.Body.String()
	
	// Vérifier que le format Prometheus est valide
	assert.Contains(t, body, "# HELP")
	assert.Contains(t, body, "# TYPE")
	
	// Vérifier que nos métriques sont présentes
	assert.True(t, strings.Contains(body, "veza_errors_total") || 
		strings.Contains(body, "go_") || 
		strings.Contains(body, "process_"),
		"Should contain Prometheus metrics")
}

func TestPrometheusMetricsEndpoint_Format(t *testing.T) {
	gin.SetMode(gin.TestMode)
	router := gin.New()
	router.GET("/metrics", PrometheusMetrics())

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

	require.Equal(t, http.StatusOK, w.Code)
	
	body := w.Body.String()
	
	// Vérifier que c'est du texte Prometheus (pas du JSON)
	assert.NotContains(t, body, `{"`)
	assert.NotContains(t, body, `"error"`)
	
	// Vérifier la présence de métriques système Prometheus
	// (go_* et process_* sont toujours présents)
	assert.True(t, strings.Contains(body, "go_") || strings.Contains(body, "process_"))
}

func TestPrometheusMetricsEndpoint_MultipleRequests(t *testing.T) {
	gin.SetMode(gin.TestMode)
	router := gin.New()
	router.GET("/metrics", PrometheusMetrics())

	// Faire plusieurs requêtes
	for i := 0; i < 3; i++ {
		w := httptest.NewRecorder()
		req := httptest.NewRequest("GET", "/metrics", nil)
		router.ServeHTTP(w, req)
		
		assert.Equal(t, http.StatusOK, w.Code)
	}
}

func TestPrometheusMetricsEndpoint_ContentType(t *testing.T) {
	gin.SetMode(gin.TestMode)
	router := gin.New()
	router.GET("/metrics", PrometheusMetrics())

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

	assert.Equal(t, http.StatusOK, w.Code)
	
	// Prometheus utilise text/plain par défaut
	contentType := w.Header().Get("Content-Type")
	assert.Contains(t, contentType, "text/plain", "Prometheus metrics should be text/plain")
}

