package apiclient

import (
	"context"
	"fmt"
	"net/http"
	"net/http/httptest"
	"sync/atomic"
	"testing"
	"time"

	"github.com/stretchr/testify/require"
)

func TestGetConditionalUsesReplaySafeRetryPolicy(t *testing.T) {
	var attempts atomic.Int32
	server := httptest.NewServer(http.HandlerFunc(func(
		writer http.ResponseWriter,
		request *http.Request,
	) {
		require.Equal(t, `"ext-v1-cached"`, request.Header.Get("If-None-Match"))
		if attempts.Add(1) == 1 {
			http.Error(writer, "retry", http.StatusServiceUnavailable)
			return
		}
		writer.Header().Set("ETag", `"ext-v2-updated"`)
		_, _ = fmt.Fprint(writer, `{"value":"updated"}`)
	}))
	defer server.Close()

	var retries atomic.Int32
	client := &Client{
		ServerURL:      server.URL,
		AuthToken:      "token",
		HTTPClient:     server.Client(),
		RecordAPIRetry: func() { retries.Add(1) },
		retry: &retryConfig{
			delays: []time.Duration{0},
			now:    time.Now,
			jitter: func(delay time.Duration) time.Duration { return delay },
			wait:   waitForRetry,
		},
	}
	var result struct {
		Value string `json:"value"`
	}
	response, err := client.GetConditional(
		context.Background(),
		"/catalog",
		`"ext-v1-cached"`,
		&result,
	)

	require.NoError(t, err)
	require.Equal(t, int32(2), attempts.Load())
	require.Equal(t, int32(1), retries.Load())
	require.Equal(t, `"ext-v2-updated"`, response.ETag)
	require.False(t, response.NotModified)
	require.Equal(t, "updated", result.Value)
}
