// +build smoke_tests

package smoke_tests

import (
	"net/http"
	"testing"

	"github.com/golang/protobuf/ptypes/wrappers"

	"code.justin.tv/live/autohost/lib"

	"code.justin.tv/live/autohost/rpc/hosting"
	"github.com/stretchr/testify/require"
)

func TestTwirpAPI_ListOperations(t *testing.T) {
	twirpClient := newHostingTwirpClient(t)

	expectedTargetIDs := []string{testUserID2, testUserID3}

	// Verify we can set an autohost list.
	ctx, cancel := getContextWithTimeout()
	defer cancel()
	setListResponse, err := twirpClient.SetAutohostList(ctx, &hosting.SetAutohostListRequest{
		CallerId:  testUserID1,
		SourceId:  testUserID1,
		TargetIds: expectedTargetIDs,
	})
	require.NoError(t, err)
	require.NotNil(t, setListResponse)
	require.Equal(t, expectedTargetIDs, setListResponse.TargetIds)

	// Verify we can fetch an autohost list.
	ctx, cancel = getContextWithTimeout()
	defer cancel()
	getAutohostListResp, err := twirpClient.GetAutohostList(ctx, &hosting.GetAutohostListRequest{
		SourceId: testUserID1,
	})
	require.NoError(t, err)
	require.NotNil(t, getAutohostListResp)
	require.Equal(t, expectedTargetIDs, getAutohostListResp.TargetIds)

	// Verify that we can remove a channel from an autohost list.
	ctx, cancel = getContextWithTimeout()
	defer cancel()
	removeFromListResp, err := twirpClient.RemoveFromAutohostList(ctx, &hosting.RemoveFromAutohostListRequest{
		CallerId:          testUserID1,
		SourceId:          testUserID1,
		TargetIdsToRemove: []string{testUserID2},
	})
	require.NoError(t, err)
	require.NotNil(t, removeFromListResp)
	require.Equal(t, []string{testUserID3}, removeFromListResp.TargetIds)

	// Verify that we can add a channel to an autohost list.
	ctx, cancel = getContextWithTimeout()
	defer cancel()
	addToListResp, err := twirpClient.AddToAutohostList(ctx, &hosting.AddToAutohostListRequest{
		CallerId:       testUserID1,
		SourceId:       testUserID1,
		TargetIdsToAdd: []string{testUserID2},
	})
	require.NoError(t, err)
	require.NotNil(t, addToListResp)
	require.Equal(t, []string{testUserID3, testUserID2}, addToListResp.TargetIds)
}

func TestTwirpAPI_Settings(t *testing.T) {
	twirpClient := newHostingTwirpClient(t)

	// Verify we can set update a user's autohost settings.
	ctx, cancel := getContextWithTimeout()
	defer cancel()
	updateSettingsResp, err := twirpClient.UpdateAutohostSettings(ctx, &hosting.UpdateAutohostSettingsRequest{
		CallerId: testUserID1,
		UserId:   testUserID1,
		Enabled: &wrappers.BoolValue{
			Value: true,
		},
		TeamHost: &wrappers.BoolValue{
			Value: false,
		},
		Strategy: hosting.AutohostStrategy_AUTOHOST_STRATEGY_ORDERED,
	})
	require.NoError(t, err)
	require.NotNil(t, updateSettingsResp)
	settings := updateSettingsResp.Settings
	require.NotNil(t, settings)
	require.True(t, settings.Enabled)
	require.False(t, settings.TeamHost)
	require.Equal(t, hosting.AutohostStrategy_AUTOHOST_STRATEGY_ORDERED, settings.Strategy)

	// Verify we can fetch a user's autohost settings.
	ctx, cancel = getContextWithTimeout()
	defer cancel()
	getSettingsResp, err := twirpClient.GetAutohostSettings(ctx, &hosting.GetAutohostSettingsRequest{
		CallerId: testUserID1,
		UserId:   testUserID1,
	})
	require.NoError(t, err)
	require.NotNil(t, getSettingsResp)
	settings = getSettingsResp.Settings
	require.NotNil(t, settings)
	require.True(t, settings.Enabled)
	require.False(t, settings.TeamHost)
	require.Equal(t, hosting.AutohostStrategy_AUTOHOST_STRATEGY_ORDERED, settings.Strategy)

}

func TestGetEndorsedChannelsAPI_CreatorOrdering(t *testing.T) {
	restClient := newRestClient(t)

	ctx, cancel := getContextWithTimeout()
	defer cancel()
	ordered := lib.AutohostStrategyOrdered
	_, err := restClient.UpdateSettings(ctx, testUserID1, testUserID1, lib.UpdateSettingsInput{
		Strategy: &ordered,
	}, nil)
	require.NoError(t, err)

	twirpClient := newHostingTwirpClient(t)

	// Verify GetEndorsedChannels runs without failing
	req := &hosting.GetEndorsedChannelsRequest{
		UserContext: &hosting.UserContext{
			DeviceId:  "testDeviceId",
			UserId:    testUserID1,
			Platform:  "web",
			Languages: []string{"en_us"},
			Country:   "us",
		},
		TargetChannelId: testUserID1,
		Limit:           10,
	}

	ctx, cancel = getContextWithTimeout()
	defer cancel()

	resp, err := twirpClient.GetEndorsedChannels(ctx, req)
	require.NoError(t, err)
	require.NotNil(t, resp)
	require.True(t, len(resp.EndorsedChannels) > 0, "resp.EndorsedChannels was empty")
}

func TestGetEndorsedChannelsAPI_RecsOrdering(t *testing.T) {
	restClient := newRestClient(t)

	ctx, cancel := getContextWithTimeout()
	defer cancel()
	ordered := lib.AutohostStrategyRandom
	_, err := restClient.UpdateSettings(ctx, testUserID1, testUserID1, lib.UpdateSettingsInput{
		Strategy: &ordered,
	}, nil)
	require.NoError(t, err)

	twirpClient := newHostingTwirpClient(t)

	// Verify GetEndorsedChannels runs without failing
	req := &hosting.GetEndorsedChannelsRequest{
		UserContext: &hosting.UserContext{
			DeviceId:  "testDeviceId",
			UserId:    testUserID1,
			Platform:  "web",
			Languages: []string{"en_us"},
			Country:   "us",
		},
		TargetChannelId: testUserID1,
		Limit:           10,
	}

	ctx, cancel = getContextWithTimeout()
	defer cancel()

	resp, err := twirpClient.GetEndorsedChannels(ctx, req)
	require.NoError(t, err)
	require.NotNil(t, resp)
	require.True(t, len(resp.EndorsedChannels) > 0, "resp.EndorsedChannels was empty")
}

func newHostingTwirpClient(t *testing.T) hosting.Hosting {
	return hosting.NewHostingProtobufClient(getBaseURL(t), &http.Client{})
}
