// +build integration

package memcached

import (
	"context"
	"testing"
	"time"

	"code.justin.tv/live/autohost/internal/hosting/config"
	"code.justin.tv/live/autohost/lib"
	"github.com/stretchr/testify/require"
)

func TestGetSettings_NotFound(t *testing.T) {
	cache := getTestCache(t)
	t.Cleanup(func() {
		clearCacheAndCloseConnection(cache)
	})

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

	settings, found, err := cache.GetSettings(ctx, "111111111")
	require.NoError(t, err)
	require.False(t, found)
	require.Nil(t, settings)
}

func TestSetSettings(t *testing.T) {
	cache := getTestCache(t)
	t.Cleanup(func() {
		clearCacheAndCloseConnection(cache)
	})

	userID := "222222222"
	expectedSettings := &lib.Settings{
		Enabled:             true,
		TeamHost:            true,
		Strategy:            lib.AutohostStrategyOrdered,
		DeprioritizeVodcast: true,
	}

	// Add settings to the cache.
	ctx, cancel := getTestContext()
	defer cancel()

	err := cache.SetSettings(ctx, userID, expectedSettings)
	require.NoError(t, err)

	// Verify that we can retrieve the settings.
	ctx, cancel = getTestContext()
	defer cancel()

	fetchedSettings, found, err := cache.GetSettings(ctx, userID)
	require.NoError(t, err)
	require.True(t, found)
	require.Equal(t, expectedSettings, fetchedSettings)
}

func TestDeleteSettings(t *testing.T) {
	cache := getTestCache(t)
	t.Cleanup(func() {
		clearCacheAndCloseConnection(cache)
	})

	userID := "333333333"

	// Add settings to the cache.
	ctx, cancel := getTestContext()
	defer cancel()

	err := cache.SetSettings(ctx, userID, &lib.Settings{})
	require.NoError(t, err)

	ctx, cancel = getTestContext()
	defer cancel()

	// Remove the settings from the cache.
	ctx, cancel = getTestContext()
	defer cancel()

	err = cache.DeleteSettings(ctx, userID)
	require.NoError(t, err)

	// Verify that the settings have been removed.
	ctx, cancel = getTestContext()
	defer cancel()

	_, found, err := cache.GetSettings(ctx, userID)
	require.NoError(t, err)
	require.False(t, found)
}

func TestDeleteSettings_NotFound(t *testing.T) {
	cache := getTestCache(t)
	t.Cleanup(func() {
		clearCacheAndCloseConnection(cache)
	})

	// Verify that deleting settings for a user that we don't have data for doesn't error.
	ctx, cancel := getTestContext()
	defer cancel()

	err := cache.DeleteSettings(ctx, "4444444444")
	require.NoError(t, err)
}

func clearCacheAndCloseConnection(cache Cache) {
	cache.FlushAll()
	cache.Close()
}

func getTestCache(t *testing.T) Cache {
	conf, err := config.GetConfig()
	require.NoError(t, err)

	env := conf.Environment
	require.True(t, env == config.EnvCI || env == config.EnvDev,
		"tests are expected to run in the Development or CI environment, but Environment was \"%s\"",
		env)

	cache, err := NewCache(conf.Memcached)
	require.NoError(t, err)
	require.NotNil(t, cache)

	return cache
}

func getTestContext() (context.Context, context.CancelFunc) {
	return context.WithTimeout(context.Background(), time.Second)
}
