package service

import (
	"bytes"
	"context"
	"io"
	"net/http"
	"testing"

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

type roundTripFunc func(*http.Request) (*http.Response, error)

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

func TestKratosAdminService_ListIdentitiesFollowsNextPagination(t *testing.T) {
	var requestedTokens []string
	client := &http.Client{Transport: roundTripFunc(func(r *http.Request) (*http.Response, error) {
		require.Equal(t, "/admin/identities", r.URL.Path)
		token := r.URL.Query().Get("page_token")
		requestedTokens = append(requestedTokens, token)

		header := make(http.Header)
		header.Set("Content-Type", "application/json")
		status := http.StatusOK
		body := "[]"
		switch token {
		case "":
			header.Set(
				"Link",
				`</admin/identities?page_size=2&page_token=identity-2>; rel="next"`,
			)
			body = `[{"id":"identity-1","traits":{"email":"one@example.com"}},{"id":"identity-2","traits":{"email":"two@example.com"}}]`
		case "identity-2":
			body = `[{"id":"identity-3","traits":{"email":"three@example.com"}}]`
		default:
			t.Fatalf("unexpected page_token %q", token)
		}
		return &http.Response{
			StatusCode: status,
			Header:     header,
			Body:       io.NopCloser(bytes.NewBufferString(body)),
			Request:    r,
		}, nil
	})}

	service := &kratosAdminService{
		AdminURL:   "http://kratos.example",
		HTTPClient: client,
	}

	identities, err := service.ListIdentities(context.Background())

	require.NoError(t, err)
	require.Equal(t, []string{"", "identity-2"}, requestedTokens)
	require.Len(t, identities, 3)
	require.Equal(t, "identity-1", identities[0].ID)
	require.Equal(t, "identity-2", identities[1].ID)
	require.Equal(t, "identity-3", identities[2].ID)
}
