// +build integration

package logic

import (
	"context"
	"fmt"
	"testing"

	"code.justin.tv/live/autohost/internal/hosting/redis"

	"code.justin.tv/live/autohost/internal/hosting/auth"
	"code.justin.tv/live/autohost/internal/hosting/clients/clue"
	"github.com/stretchr/testify/require"
)

func TestHost(t *testing.T) {
	t.Run("host succeeds", func(t *testing.T) {
		callerID := NewRandomUserID()
		sourceID := NewRandomUserID()
		targetID := NewRandomUserID()

		mockClue := &clue.MockClient{}
		mockClue.On("Host", context.Background(), sourceID, targetID, false, false).Return(nil).Once()

		testEnv := newTestEnv(t, &Params{
			ClueClient: mockClue,
			Auth:       auth.NewAllowAllStub(),
		})
		l := testEnv.logic

		err := l.HostTarget(context.Background(), callerID, sourceID, targetID)
		require.NoError(t, err)
	})

	t.Run("host fails", func(t *testing.T) {
		callerID := NewRandomUserID()
		sourceID := NewRandomUserID()
		targetID := NewRandomUserID()

		resErr := fmt.Errorf("mocked hostmode.Host error")
		mockClue := &clue.MockClient{}
		mockClue.On("Host", context.Background(), sourceID, targetID, false, false).Return(resErr).Once()

		testEnv := newTestEnv(t, &Params{
			ClueClient: mockClue,
			Auth:       auth.NewAllowAllStub(),
		})
		l := testEnv.logic

		err := l.HostTarget(context.Background(), callerID, sourceID, targetID)
		require.Error(t, err)
	})

	t.Run("user is not authorized", func(t *testing.T) {
		callerID := NewRandomUserID()
		sourceID := NewRandomUserID()
		targetID := NewRandomUserID()

		mockClue := &clue.MockClient{}
		mockClue.On("Host", context.Background(), sourceID, targetID, false, false).Return(nil)

		testEnv := newTestEnv(t, &Params{
			ClueClient: mockClue,
			Auth:       auth.NewDenyAllStub(),
		})
		l := testEnv.logic

		err := l.HostTarget(context.Background(), callerID, sourceID, targetID)
		require.Error(t, err)
		require.Equal(t, "Forbidden", err.Error())
	})

	t.Run("user is rate limited", func(t *testing.T) {
		callerID := NewRandomUserID()
		sourceID := callerID
		targetID := NewRandomUserID()

		mockClue := &clue.MockClient{}
		mockClue.On("Host", context.Background(), sourceID, targetID, false, false).Return(nil)

		testEnv := newTestEnv(t, &Params{
			ClueClient:  mockClue,
			Auth:        auth.NewAllowAllStub(),
			RateLimiter: redis.NewRateLimiterStub(false),
		})
		l := testEnv.logic

		err := l.HostTarget(context.Background(), callerID, sourceID, targetID)
		require.Error(t, err)
		require.Equal(t, "TooManyRequests", err.Error())
	})
}
