// ConnectClient.cpp : 定义控制台应用程序的入口点。
//

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include "pgLibConnect.h"

void LogOutput(unsigned int uLevel, const char* lpszOut)
{
	printf("%s", lpszOut);
}

int main(int argc, char* argv[])
{
	srand((unsigned int)time(0));

	char szDevID[128] = {0};
	char szSvrAddr[128] = {0};
	char szRelayAddr[128] = {0};

	printf("Input the device id: ");
	gets(szDevID);
	if (szDevID[0] == '\0') {
		strcpy(szDevID, "1111");
	}

	printf("Input the server address: ");
	gets(szSvrAddr);
	if (szSvrAddr[0] == '\0') {
		strcpy(szSvrAddr, "connect.peergine.com:7781");
	}

	printf("Input the relay address: ");
	GetInput(szRelayAddr);
	if (szRelayAddr[0] == '\0') {
		strcpy(szRelayAddr, "relay.peergine.com:443");
	}

	char szRelayInfo[256] = {0};
	sprintf(szRelayInfo, "type=0&load=0&addr=%s", szRelayAddr);

	pgSetConfig("(NetCardFilterMode){2}(NetCardFilterList){utun*,docker*,*vpn*,zt*,veth*}");

	unsigned int uInstID = 0;
	PG_INIT_CFG_S stInitCfg;
	memset(&stInitCfg, 0, sizeof(stInitCfg));

	if (pgInitialize(&uInstID, PG_MODE_CLIENT, "test_mac", "",
		szSvrAddr, szRelayInfo, &stInitCfg, LogOutput) != PG_ERROR_OK)
	{
		printf("Init peergine module failed.\n");
		return 0;
	}

	printf("Init peergine module success.\n");

	char szCltID[128] = {0};
	pgSelf(uInstID, szCltID, sizeof(szCltID));
	printf("Client ID: %s\n", szCltID);

	unsigned int uSessID = 0;
	unsigned int uSwitch = 0;
	while (1) {

		if (uSessID == 0) {
			int iErr = pgOpen(uInstID, szDevID, &uSessID);
			if (iErr != PG_ERROR_OK) {
				printf("pgOpen: iErr=%d\n", iErr);
			}
		}

		unsigned int uEventNow = PG_EVENT_NULL;
		unsigned int uSessIDNow = 0;
		unsigned int uPrio = 0;
		int iErr = pgEvent(uInstID, &uEventNow, &uSessIDNow, &uPrio, 10000);
		if (iErr != PG_ERROR_OK) {
			if (iErr != PG_ERROR_TIMEOUT) {
				printf("pgEvent: iErr=%d\n", iErr);
			}

			char szBuf[128] = {0};
			if (uSwitch) {
				strcpy(szBuf, "Switch Off");
				uSwitch = 0;
			}
			else {
				strcpy(szBuf, "Switch On");
				uSwitch = 1;
			}

			iErr = pgWrite(uInstID, uSessID, szBuf, strlen(szBuf), PG_PRIORITY_1);
			if (iErr < 0) {
				printf("pgWrite: iErr=%d\n", iErr);
			}

			// Start to scan lan p2p id.
			pgLanScanStart(uInstID);

			continue;
		}

		if (uEventNow == PG_EVENT_CONNECT) {
			printf("CONNECT: SessID=%u\n", uSessIDNow);

			const char* pszData = "Hello";
			iErr = pgWrite(uInstID, uSessIDNow, pszData, strlen(pszData), PG_PRIORITY_1);
			if (iErr < 0) {
				printf("pgWrite: iErr=%d\n", iErr);
			}
		}
		else if (uEventNow == PG_EVENT_INFO) {
			printf("INFO: SessID=%u\n", uSessIDNow);

			PG_INFO_S stInfo;
			int iRet = pgInfo(uInstID, uSessIDNow, &stInfo);
			if (iRet == PG_ERROR_OK) {
				printf("pgInfo: PeerID=%s, AddrPub=%s, AddrPriv=%s, ListenID=%s, CnntType=%u\n",
					stInfo.szPeerID, stInfo.szAddrPub, stInfo.szAddrPriv, stInfo.szListenID, stInfo.uCnntType);
			}
		}
		else if (uEventNow == PG_EVENT_CLOSE) {
			printf("CLOSE: SessID=%u\n", uSessIDNow);
			pgClose(uInstID, uSessIDNow);
			uSessID = 0;
		}
		else if (uEventNow == PG_EVENT_READ) {
			printf("READ: SessID=%u, uPrio=%u\n", uSessIDNow, uPrio);

			char szBuf[24 * 1024] = {0};
			unsigned int uPrio1 = 0;
			int iRet = pgRead(uInstID, uSessIDNow, szBuf, sizeof(szBuf), &uPrio1);
			if (iRet < 0) {
				printf("pgRead: iErr=%d\n", iRet);
			}
			else {
				szBuf[iRet] = '\0';
				printf("REPLY: %s\n", szBuf);
			}
		}
		else if (uEventNow == PG_EVENT_WRITE) {
			printf("WRITE: SessID=%u, uPrio=%u\n", uSessIDNow, uPrio);
		}
		else if (uEventNow == PG_EVENT_OFFLINE) {
			printf("OFFLINE: SessID=%u\n", uSessIDNow);
		}
		else if (uEventNow == PG_EVENT_SVR_LOGIN) {
			printf("SVR_LOGIN:\n");

			int iRet = pgServerRequest(uInstID, "Report: test", 0);
			if (iRet != PG_ERROR_OK) {
				printf("pgServerRequest: iErr=%d\n", iRet);
			}
		}
		else if (uEventNow == PG_EVENT_SVR_LOGOUT) {
			printf("SVR_LOGOUT:\n");
		}
		else if (uEventNow == PG_EVENT_SVR_REPLY) {
			printf("SVR_REPLY:\n");

			char szBuf[2048] = {0};
			unsigned int uParam = 0;
			int iRet = pgServerReply(uInstID, szBuf, sizeof(szBuf), &uParam);
			if (iRet < PG_ERROR_OK) {
				printf("pgServerReply: iErr=%d\n", iRet);
				continue;
			}

			szBuf[iRet] = '\0';
			printf("Reply: %s\n", szBuf);
		}
		else if (uEventNow == PG_EVENT_SVR_NOTIFY) {
			printf("SVR_NOTIFY:\n");

			char szBuf[2048] = {0};
			unsigned int uParam = 0;
			int iRet = pgServerNotify(uInstID, szBuf, sizeof(szBuf));
			if (iRet < PG_ERROR_OK) {
				printf("pgServerNotify: iErr=%d\n", iRet);
				continue;
			}

			szBuf[iRet] = '\0';
			printf("Notify: %s\n", szBuf);
		}
		else if (uEventNow == PG_EVENT_LAN_SCAN) {
			printf("LAN_SCAN:\n");

			PG_LAN_SCAN_S stLanList[8];
			int iRet = pgLanScanResult(uInstID, stLanList, 8);
			if (iRet > PG_ERROR_OK) {
				for (unsigned int uInd = 0; uInd < iRet; uInd++) {
					printf("ID=%s, Addr=%s\n", stLanList[uInd].szListenID, stLanList[uInd].szAddr);
				}
			}
		}
	}


	pgCleanup(uInstID);
	printf("Clean peergine module.");

	getchar();
}

