#include "pch.h"
#include "http/HttpRequestUtil.h"
#include "Internal.h"

using namespace TwitchInGames;

tstring BrowserAuth::GetToken() const {
	return token;
}

std::future<tstring> BrowserAuth::Launch(string_t clientId, string_t redirectUri, string_t responseType, std::vector<string_t> const& scopes, tstring& state, string_t scheme/*= nullptr*/) {
	// Send a science event.
	tstring scope;
	for(auto s : scopes) {
		scope.append(s);
		scope.append(_T(" "));
	}
	scope.pop_back();
	SendUserScienceEvent(clientId, tstring(), _T("sdk_auth_sign_in"), { { _T("scopes"), scope } });

	// Compose the authentication URL.
	token.clear();
	tstring const escapedResponseType= UrlEncode(responseType);
	tstring const escapedClientId= UrlEncode(clientId);
	tstring const escapedRedirectUri= UrlEncode(redirectUri);
	tstring const escapedScope= UrlEncode(scope);
	tstring url= _T("https://id.twitch.tv/oauth2/authorize?response_type=") + escapedResponseType +
		_T("&client_id=") + escapedClientId +
		_T("&redirect_uri=") + escapedRedirectUri +
		_T("&scope=") + escapedScope;

	// Include thirty-two characters of random state.
	state.clear();
	std::generate_n(std::back_inserter(state), 32, []() {
		unsigned int value;
		rand_s(&value);
		return static_cast<tstring::value_type>(((value & 0x6f) | 0x40) + 1);
	});
	url += _T("&state=");
	url += state;

	// Open the platform's browser.
	return Launch(url.c_str(), state, scheme);
}
