/*! \example stove_pc_matchmaking_sample.cpp
*  \brief 콘솔 샘플 프로그램입니다. <BR>
*	이 예제 프로그램은 Matchmaking SDK 사용 방법을 단계별로 설명합니다. 
*	-# 콜백 등록
*		- ::StovePCMatchmaking_Init(초기화 함수) 호출 전 / 후 아무때나 등록할 수 있습니다.
*	-# ::StovePCMatchmaking_Init로 SDK를 초기화합니다.
*	-# ::StovePCMatchmaking_Connect 로 매치메이킹 서버에 접속합니다.
*	-# 로비 생성 / 검색 / 입장 / 퇴장 합니다.
*	-# ::StovePCMatchmaking_Disconnect 로 매치메이킹 서버에서 접속을 종료합니다.
*	-# ::StovePCMatchmaking_UnInit 로 SDK 를 해제합니다.
*  \warning 매치메이킹은 스토브 PC SDK가 실행된 상태에서만 작동합니다.
*/
#include "stdafx.h"

#include <memory>
#include <vector>
#include "stove_pc_matchmaking_sample.h"
#include <StovePCMatchmakingSDK.h>

std::wstring myLobby;

int main(int argc, char* argv[])
{			
	// 비동기 API 실행후 에러나 서버에서 실패를 반환시 콜백합니다.
	StovePCMatchmakingCallback callbackFunc = {};
	
	// 각 비동기 API는 1:1로 매칭된 콜백이 있습니다.
	callbackFunc.OnConnect = OnConnect;
	callbackFunc.OnDisconnect = OnDisconnect;
	callbackFunc.OnCreateLobby = OnCreateLobby;
	callbackFunc.OnJoinLobby = OnJoinLobby;
	callbackFunc.OnLeaveLobby = OnLeaveLobby;

	// 서버로부터의 알림 이벤트 콜백입니다.
	// 로비에 새로운 유저 입장을 알리는 콜백
	callbackFunc.OnUserJoin = OnUserJoin;
	// 로비 내 유저가 퇴장을 알리는 콜백
	callbackFunc.OnUserLeave = OnUserLeave;	
	// 로비 설정 수정을 알리는 콜백
	callbackFunc.OnUpdateLobbyData = OnUpdateLobbyData;
	// 로비 유저의 상태값 수정을 알리는 콜백 ( 유저 상태 : 등급, 유저 설정 데이터 등 )
	callbackFunc.OnUpdateLobbyUser = OnUpdateLobbyUser;

	// 1. SDK에 콜백을 등록합니다. 초기화 함수 호출과 무관하게 등록할 수 있습니다.
	StovePCMatchmaking_RegisterCallback(callbackFunc);

	// 2. SDK 초기화
	StovePCMatchmaking_Init(StovePCMatchmakingLogLevel::STOVE_PC_MATCHMAKING_DEBUG);
	
	// 3. matchmaking 서버에 접속
	std::wstring nickname = L"nick18";
	StovePCMatchmaking_Connect(nickname.c_str());

	short abort = 0;
    while ( !abort )
    {
		std::wstring input;				
		std::wcout << L">> ";

		while ( std::getline(std::wcin, input) )
        { 			            						
			if (0 == input.compare(L"join"))
			{
				// ::StovePCMatchmaking_JoinRandomLobby는 검색 조건이 비교 연산자 "="로 고정됩니다.
				// "mode = 1"인 로비를 검색한다면
				std::wstring condition1_key = L"mode";	// 로비 검색시 사용할 키
				std::wstring condition1_val = L"1";		// 로비 검색시 사용할 값				

				std::vector<StovePCMatchmakingMetadata> conds;
				conds.emplace_back(StovePCMatchmakingMetadata{
					const_cast<wchar_t*>(condition1_key.c_str()),
					const_cast<wchar_t*>(condition1_val.c_str())
				});

				// 검색된 로비가 없을시 최대 인원수 2명으로 로비를 생성합니다.
				int32_t maxUser = 2;

				// 3. 검색 조건에 매칭되는 로비 입장, 
				// 검색된 로비중 하나에 자동으로 참여합니다. 검색된 로비가 없을시 로비를 자동으로 생성합니다.
				StovePCMatchmaking_JoinRandomLobby(conds.data(), conds.size(), maxUser);
				break;
			}
			if (0 == input.compare(L"leave"))
			{
				// 5. matchmaking 로비 퇴장
				StovePCMatchmaking_LeaveLobby(myLobby.c_str());
				break;
			}			
			if (0 == input.compare(L"disconnect"))
			{
				// 6. matchmaking 서버에서 접속 종료
				StovePCMatchmaking_Disconnect();
				break;
			}
			else if (0 == input.compare(L""))
			{
				// 큐에 있는 콜백 객체를 가져옵니다.
				// StovePCMatchmaking_RunCallback 실행전까지 큐에 저장된 콜백 객체는 호출되지 않습니다.
				StovePCMatchmaking_RunCallback();
				break;
			}
			else if (0 == input.compare(L"quit"))
            {
				// 7. SDK 자원해제
				StovePCMatchmaking_UnInit();

				// 콘솔 프로그램 종료
                abort = 1;
                break;
            }			
			else
            {
				std::wcout << L"Unknown Command." << std::endl;
                break;
            }

			std::wcout << std::endl;
        }
    }    

    return 0;
}