package gitcred

import (
	"context"
	"net/http"
	"testing"
	"time"

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

func TestRefreshableTokenAuthUsesSeedUntilNearExpiry(t *testing.T) {
	calls := 0
	auth := NewRefreshableTokenAuth("ags_rat_seed", time.Now().Add(time.Hour), func(context.Context) (string, time.Time, error) {
		calls++
		return "ags_rat_next", time.Now().Add(time.Hour), nil
	})

	req, err := http.NewRequest(http.MethodGet, "https://agentteam.test/repo.git/info/refs", nil)
	require.NoError(t, err)
	auth.SetAuth(req)

	require.Equal(t, "Bearer ags_rat_seed", req.Header.Get("Authorization"))
	require.Zero(t, calls)
}

func TestRefreshableTokenAuthRefreshesNearExpiry(t *testing.T) {
	calls := 0
	auth := NewRefreshableTokenAuth("ags_rat_old", time.Now().Add(time.Second), func(context.Context) (string, time.Time, error) {
		calls++
		return "ags_rat_new", time.Now().Add(time.Hour), nil
	})

	req, err := http.NewRequest(http.MethodGet, "https://agentteam.test/repo.git/info/refs", nil)
	require.NoError(t, err)
	auth.SetAuth(req)

	require.Equal(t, "Bearer ags_rat_new", req.Header.Get("Authorization"))
	require.Equal(t, 1, calls)
}

func TestParseTokenLeaseAndRefreshableLeaseAuth(t *testing.T) {
	lease, err := ParseTokenLease(" ags_rat_seed ", "2099-01-02T03:04:05Z")
	require.NoError(t, err)
	require.Equal(t, "ags_rat_seed", lease.Token)

	auth := NewRefreshableLeaseAuth(lease, func(context.Context) (TokenLease, error) {
		return TokenLease{Token: "ags_rat_next", ExpiresAt: time.Now().Add(time.Hour)}, nil
	})

	req, err := http.NewRequest(http.MethodGet, "https://agentteam.test/repo.git/info/refs", nil)
	require.NoError(t, err)
	auth.SetAuth(req)

	require.Equal(t, "Bearer ags_rat_seed", req.Header.Get("Authorization"))
}
