package http_round_tripper

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

	"github.com/prometheus/client_golang/prometheus"
	"github.com/prometheus/client_golang/prometheus/testutil"
	"github.com/stretchr/testify/require"
)

type roundTripFunc func(req *http.Request) *http.Response

func (f roundTripFunc) RoundTrip(req *http.Request) (*http.Response, error) {
	return f(req), nil
}

func TestNewFactory(t *testing.T) {
	factoryOpts := []FactoryOption{
		WithNamespace("namespace"),
		WithLabels("label1", "label2"),
		WithRequestDurationBuckets([]float64{1, 2, 3}),
	}

	opts := []Option{
		WithLabelValues(map[string]string{"label1": "1", "label2": "1"}),
	}

	applyMetrics := NewFactory(factoryOpts...)

	var invoked bool
	roundTripper := applyMetrics(roundTripFunc(func(req *http.Request) *http.Response {
		invoked = true

		return &http.Response{}
	}), opts...)

	r := httptest.NewRequest("GET", "http://example.com", nil)
	roundTripper.RoundTrip(r)

	metrics := []string{
		"namespace_http_" + inFlightRequestsMetricName,
		"namespace_http_" + requestsTotalMetricName,
	}

	expected := strings.NewReader(`
				# HELP namespace_http_in_flight_requests A gauge of requests currently being handled.
				# TYPE namespace_http_in_flight_requests gauge
				namespace_http_in_flight_requests 0
				# HELP namespace_http_requests_total A counter for total number of requests.
				# TYPE namespace_http_requests_total counter
				namespace_http_requests_total{code="200",label1="1",label2="1",method="get"} 1
			`)
	err := testutil.GatherAndCompare(prometheus.DefaultGatherer, expected, metrics...)
	require.NoError(t, err)

	// Duration value is unreliable, so let's just check that the metric is counted
	count, err := testutil.GatherAndCount(prometheus.DefaultGatherer, "namespace_http_"+requestDurationSecondsMetricName)
	require.NoError(t, err)
	require.Equal(t, 1, count)

	require.True(t, invoked, "request was not executed")
}
