#include "pch.h"
#ifdef _WIN32
# include <objbase.h>
#endif
#include "Chat_.h"

using namespace TwitchInGames;

TWITCH_SDK_DLL_API Chat* TwitchInGames::CreateChat() {
	return new Chat();
}

TWITCH_SDK_DLL_API void TwitchInGames::DeleteChat(Chat*& chat) {
	delete chat;
	chat = nullptr;
}

TWITCH_SDK_DLL_API HRESULT TwitchInGames::SignInChat(Chat* chat, string_t clientId, string_t token, string_t& login) {
	try {
		chat->SignIn(clientId, token).get();
		login = _tcsdup(chat->Login.c_str());
		return S_OK;
	} catch(TwitchException const& ex) {
		return ex.ErrorCode < 0 ? ex.ErrorCode :
			ex.ErrorCode < 500 ? HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED) :
			HRESULT_FROM_WIN32(ex.ErrorCode);
	} catch(...) {
		return E_FAIL;
	}
}

TWITCH_SDK_DLL_API HRESULT TwitchInGames::SignOutChat(Chat* chat) {
	try {
		chat->SignOut().get();
		return S_OK;
	} catch(TwitchException const& ex) {
		return ex.ErrorCode < 0 ? ex.ErrorCode : HRESULT_FROM_WIN32(ex.ErrorCode);
	} catch(...) {
		return E_FAIL;
	}
}

TWITCH_SDK_DLL_API HRESULT TwitchInGames::JoinChannel(Chat* chat, string_t channelName, ChatChannelReceiveCallback receiveCallback, std::shared_ptr<Chat::Channel>*& channel) {
	auto fn = [receiveCallback](Chat::Channel& channel, tstring const& userName, tstring const& message) {
		receiveCallback(channel, userName.c_str(), message.c_str());
	};
	try {
		channel = new std::shared_ptr<Chat::Channel>(chat->JoinChannel(channelName, fn).get());
		return S_OK;
	} catch(TwitchException const& ex) {
		return ex.ErrorCode < 0 ? ex.ErrorCode :
			ex.ErrorCode < 500 ? HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED) :
			HRESULT_FROM_WIN32(ex.ErrorCode);
	} catch(...) {
		return E_FAIL;
	}
}

TWITCH_SDK_DLL_API void TwitchInGames::DepartChannel(std::shared_ptr<Chat::Channel>*& channel) {
	try {
		(*channel)->Depart().get();
	} catch(...) {
		// Ignore exceptions.
	}
	delete channel;
	channel = nullptr;
}

TWITCH_SDK_DLL_API HRESULT TwitchInGames::SendLineToChannel(std::shared_ptr<Chat::Channel>* channel, string_t message) {
	try {
		(*channel)->SendLine(message).get();
		return S_OK;
	} catch(TwitchException const& ex) {
		return ex.ErrorCode < 0 ? ex.ErrorCode :
			ex.ErrorCode < 500 ? HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED) :
			HRESULT_FROM_WIN32(ex.ErrorCode);
	} catch(...) {
		return E_FAIL;
	}
}
