package store_test

import (
	"context"
	"testing"

	"github.com/stretchr/testify/require"

	"git.d-ma.be/mathias/tapir/internal/adapters/store"
)

func TestSetTranscriptStatus_RoundTrip(t *testing.T) {
	ctx := context.Background()
	s := newStore(t)
	resetDB(t, rawPool(t))

	id, err := s.UpsertVideo(ctx, ytVideo(userA, "rt12345", "round trip"))
	require.NoError(t, err)

	// Unset by default.
	got, err := s.GetTranscriptStatus(ctx, userA, id)
	require.NoError(t, err)
	require.Equal(t, "", got)

	for _, status := range []string{"none", "fetched", "rate_limited", ""} {
		require.NoError(t, s.SetTranscriptStatus(ctx, userA, id, status))
		got, err := s.GetTranscriptStatus(ctx, userA, id)
		require.NoError(t, err)
		require.Equal(t, status, got)
	}
}

func TestSetTranscriptStatus_RejectsInvalid(t *testing.T) {
	ctx := context.Background()
	s := newStore(t)
	resetDB(t, rawPool(t))

	id, err := s.UpsertVideo(ctx, ytVideo(userA, "bad12345", "bad status"))
	require.NoError(t, err)

	require.Error(t, s.SetTranscriptStatus(ctx, userA, id, "bogus"))

	// The rejected write left the status untouched.
	got, err := s.GetTranscriptStatus(ctx, userA, id)
	require.NoError(t, err)
	require.Equal(t, "", got)
}

func TestSetTranscriptStatus_NotFound(t *testing.T) {
	ctx := context.Background()
	s := newStore(t)
	resetDB(t, rawPool(t))

	require.ErrorIs(t, s.SetTranscriptStatus(ctx, userA, videoX, "fetched"), store.ErrNotFound)

	_, err := s.GetTranscriptStatus(ctx, userA, videoX)
	require.ErrorIs(t, err, store.ErrNotFound)
}

func TestRateLimitedVideoIDs_StampsAndClears(t *testing.T) {
	ctx := context.Background()
	s := newStore(t)
	resetDB(t, rawPool(t))

	id, err := s.UpsertVideo(ctx, ytVideo(userA, "rl12345", "rate limited"))
	require.NoError(t, err)

	// Marking rate_limited stamps rate_limited_at, so the video appears.
	require.NoError(t, s.SetTranscriptStatus(ctx, userA, id, "rate_limited"))
	rl, err := s.RateLimitedVideoIDs(ctx, userA)
	require.NoError(t, err)
	require.Contains(t, rl, id)
	require.False(t, rl[id].IsZero(), "rate_limited_at must be stamped")

	// Moving off rate_limited clears the timestamp, so it drops out.
	require.NoError(t, s.SetTranscriptStatus(ctx, userA, id, "fetched"))
	rl, err = s.RateLimitedVideoIDs(ctx, userA)
	require.NoError(t, err)
	require.NotContains(t, rl, id)
}
