// +build smoke_tests

package smoke_tests

import (
	"context"
	"os"
	"strings"
	"testing"
	"time"

	"code.justin.tv/foundation/twitchclient"
	autohost "code.justin.tv/live/autohost/client"
	"code.justin.tv/live/autohost/lib"
	"github.com/stretchr/testify/require"
)

const (
	testUserID1 = "264863151" // user ihatepinacoladas
	testUserID2 = "153061467" // user ihatebadwords
	testUserID3 = "438703140" // user ihatedehydration
)

func TestAutoHostSettingsRestAPI_Settings(t *testing.T) {
	client := newRestClient(t)

	ctx, cancel := getContextWithTimeout()
	defer cancel()
	ordered := lib.AutohostStrategyOrdered
	enabled := true
	settings, err := client.UpdateSettings(ctx, testUserID1, testUserID1, lib.UpdateSettingsInput{
		Strategy: &ordered,
		Enabled:  &enabled,
	}, nil)
	require.NoError(t, err)
	require.NotNil(t, settings)
	require.Equal(t, lib.AutohostStrategyOrdered, settings.Strategy)
	require.True(t, settings.Enabled)

	ctx, cancel = getContextWithTimeout()
	defer cancel()
	settings, err = client.GetSettings(ctx, testUserID1, testUserID1, nil)
	require.NoError(t, err)
	require.NotNil(t, settings)
	require.Equal(t, lib.AutohostStrategyOrdered, settings.Strategy)
	require.True(t, settings.Enabled)
}

func TestHostingRestAPI(t *testing.T) {
	client := newRestClient(t)

	ctx, cancel := getContextWithTimeout()
	defer cancel()
	unhost, err := client.Unhost(ctx, testUserID1, testUserID1, nil)
	require.NoError(t, err)
	require.NotNil(t, unhost)

	ctx, cancel = getContextWithTimeout()
	defer cancel()
	host, err := client.HostTarget(ctx, testUserID1, testUserID1, testUserID2, nil)
	require.NoError(t, err)
	require.NotNil(t, host)
	require.Equal(t, testUserID1, host.ChannelID)
	require.Equal(t, testUserID2, host.TargetID)

	ctx, cancel = getContextWithTimeout()
	defer cancel()
	unhost, err = client.Unhost(ctx, testUserID1, testUserID1, nil)
	require.NoError(t, err)
	require.NotNil(t, unhost)
}

func TestHostingRestAPI_AlreadyHostingErr(t *testing.T) {
	client := newRestClient(t)

	ctx, cancel := getContextWithTimeout()
	defer cancel()
	_, err := client.Unhost(ctx, testUserID1, testUserID1, nil)
	require.NoError(t, err)

	ctx, cancel = getContextWithTimeout()
	defer cancel()
	_, err = client.HostTarget(ctx, testUserID1, testUserID1, testUserID2, nil)
	require.NoError(t, err)

	ctx, cancel = getContextWithTimeout()
	defer cancel()
	time.Sleep(time.Second)
	_, err = client.HostTarget(ctx, testUserID1, testUserID1, testUserID2, nil)
	require.Error(t, err)
	r, ok := err.(*twitchclient.Error)
	require.Equal(t, true, ok)
	require.Equal(t, string(lib.ErrAlreadyHosting), r.Message)
}

func TestHostingRestAPI_CannotHostSelfErr(t *testing.T) {
	client := newRestClient(t)

	ctx, cancel := getContextWithTimeout()
	defer cancel()

	_, err := client.HostTarget(ctx, testUserID1, testUserID1, testUserID1, nil)
	require.Error(t, err)

	r, ok := err.(*twitchclient.Error)
	require.Equal(t, true, ok)
	require.Equal(t, string(lib.ErrCannotHostSelf), r.Message)
}

func getBaseURL(t *testing.T) string {
	env := os.Getenv("ENVIRONMENT")
	env = strings.ToLower(env)
	if env != "production" && env != "staging" && env != "development" {
		t.Fatalf("Environment variable, \"ENVIRONMENT\" was set to, \"%s\", but is expected to be set to \"production\", \"staging\", or \"development\".", env)
		return ""
	}
	t.Logf("ENVIRONMENT: %s", env)

	baseURL := ""
	switch env {
	case "production":
		baseURL = "http://main.us-west-2.prod.autohost.twitch.a2z.com"
	case "staging":
		baseURL = "http://main.us-west-2.staging.autohost.twitch.a2z.com"
	case "development":
		baseURL = "http://localhost:8000"
	}

	t.Logf("AutoHost Base URL: %s", baseURL)
	return baseURL
}

func newRestClient(t *testing.T) autohost.Client {
	base := getBaseURL(t)
	conf := twitchclient.ClientConf{
		Host: base,
	}
	client, err := autohost.NewClient(conf)
	require.NoError(t, err)
	require.NotNil(t, client)

	return client
}

func getContextWithTimeout() (context.Context, context.CancelFunc) {
	return context.WithTimeout(context.Background(), 5*time.Second)
}
