#include "pch.h"
#include "../../lib/Shared/Internal.h"
#include "Utilities.h"
#ifndef GTEST_OS_WINDOWS
# include "StreamTest.h"
#endif

using namespace TwitchInGames;
using namespace Utilities;

TEST(StreamTest, FetchDefaultStreams_Success) {
	StreamsRequest streamsRequest;
	auto streamResponse = streamsRequest.Fetch(clientId, token).get();
	EXPECT_NE(streamResponse.Cursor, _T(""));
	EXPECT_GE(streamResponse.Streams.size(), 0u);

	for(auto const& stream : streamResponse.Streams) {
		EXPECT_GE(stream.CommunityIds.size(), 0u);
		EXPECT_NE(stream.Id, _T(""));
		EXPECT_NE(stream.Language, _T(""));
		EXPECT_NE(stream.StartedAt, NULL);
		EXPECT_NE(stream.ThumbnailUrl, _T(""));
		EXPECT_TRUE(stream.Type == Stream::StreamType::Live || stream.Type == Stream::StreamType::None || stream.Type == Stream::StreamType::Vodcast);
		EXPECT_NE(stream.UserId, _T(""));
		EXPECT_GE(stream.ViewerCount, 1u);
	}
}

TEST(StreamTest, FetchOfflineUserStreams_Fail) {
	StreamsRequest streamsRequest;
	streamsRequest.UserLogin = login;
	auto streamResponse = streamsRequest.Fetch(clientId, token).get();
	EXPECT_EQ(streamResponse.Cursor, _T(""));
	EXPECT_EQ(streamResponse.Streams.size(), 0u);
}

TEST(StreamTest, FetchStreamByDisplayName_Success) {
	StreamsRequest streamsRequest;
	streamsRequest.Count = 1;
	auto streamResponse = streamsRequest.Fetch(clientId, token).get();
	EXPECT_NE(streamResponse.Cursor, _T(""));
	EXPECT_LE(streamResponse.Streams.size(), 1u);
	if(!streamResponse.Streams.empty()) {
		tstring topUserId = streamResponse.Streams[0].UserId;
		auto user = User::FetchOtherById(clientId, topUserId).get();
		streamsRequest.UserLogin = user.DisplayName;
		streamResponse = streamsRequest.Fetch(clientId, token).get();
		if(!streamResponse.Streams.empty()) {
			EXPECT_EQ(topUserId, streamResponse.Streams[0].UserId);
		} else {
			WriteWarning("[FetchStreamByDisplayName_Success] no streams");
		}
	}
}

TEST(StreamTest, FetchForwardThenBackward_Success) {
	StreamsRequest streamsRequest;
	streamsRequest.Count = 5;
	auto streamResponse = streamsRequest.Fetch(clientId, token).get();
	EXPECT_NE(streamResponse.Cursor, _T(""));
	EXPECT_LE(streamResponse.Streams.size(), 5u);

	streamsRequest.Cursor = streamResponse.Cursor;
	streamsRequest.Direction = StreamsRequest::PaginationDirection::Forward;
	streamResponse = streamsRequest.Fetch(clientId, token).get();
	EXPECT_NE(streamResponse.Cursor, _T(""));
	EXPECT_LE(streamResponse.Streams.size(), 5u);

	streamsRequest.Cursor = streamResponse.Cursor;
	streamsRequest.Direction = StreamsRequest::PaginationDirection::Backward;
	streamResponse = streamsRequest.Fetch(clientId, token).get();
	EXPECT_NE(streamResponse.Cursor, _T(""));
	EXPECT_LE(streamResponse.Streams.size(), 5u);
}

TEST(StreamTest, FetchBackward_Fail) {
	StreamsRequest streamsRequest;
	streamsRequest.Count = 5;
	auto streamResponse = streamsRequest.Fetch(clientId, token).get();
	EXPECT_NE(streamResponse.Cursor, _T(""));
	EXPECT_LE(streamResponse.Streams.size(), 5u);

	streamsRequest.Cursor = streamResponse.Cursor;
	streamsRequest.Direction = StreamsRequest::PaginationDirection::Backward;
	EXPECT_ANY_THROW(streamsRequest.Fetch(clientId, token).get());
}

tostream& operator<<(tostream& os, Stream::StreamType type) {
	os << static_cast<int>(type);
	return os;
}

TEST(StreamTest, FetchTopStream_Success) {
	StreamsRequest streamsRequest;
	streamsRequest.Count = 1;
	auto streamResponse = streamsRequest.Fetch(clientId, token).get();
	EXPECT_NE(streamResponse.Cursor, _T(""));
	EXPECT_LE(streamResponse.Streams.size(), 1u);


	streamsRequest.UserId = streamResponse.Streams[0].UserId;
	streamsRequest.Count = 0;
	auto streamResponse2 = streamsRequest.Fetch(clientId, token).get();

	EXPECT_EQ(streamResponse.Cursor, streamResponse2.Cursor);
	EXPECT_EQ(streamResponse.Streams.size(), streamResponse2.Streams.size());
	EXPECT_EQ(streamResponse.Streams[0].CommunityIds.size(), streamResponse2.Streams[0].CommunityIds.size());
	EXPECT_EQ(streamResponse.Streams[0].GameId, streamResponse2.Streams[0].GameId);
	EXPECT_EQ(streamResponse.Streams[0].Id, streamResponse2.Streams[0].Id);
	EXPECT_EQ(streamResponse.Streams[0].Language, streamResponse2.Streams[0].Language);
	EXPECT_EQ(streamResponse.Streams[0].StartedAt, streamResponse2.Streams[0].StartedAt);
	EXPECT_EQ(streamResponse.Streams[0].ThumbnailUrl, streamResponse2.Streams[0].ThumbnailUrl);
	EXPECT_EQ(streamResponse.Streams[0].Title, streamResponse2.Streams[0].Title);
	EXPECT_EQ(streamResponse.Streams[0].Type, streamResponse2.Streams[0].Type);
	EXPECT_EQ(streamResponse.Streams[0].UserId, streamResponse2.Streams[0].UserId);
}
