
#include <iostream>
#include <winsock.h>   
#include <stdio.h>   
#include "./../system_basic_info/SystemAnalysis.h"
#include "debug_server_socket.h"

using namespace std;

#define PORT  6123
#define MSGSIZE  1024

#pragma warning(disable: 4018)
#pragma warning(disable: 4996)
#pragma comment(lib, "ws2_32.lib")

#define CLIENT_SOCKET_NUM_MAX    20
int g_iTotalConn = 0;
SOCKET g_CliSocketArr[CLIENT_SOCKET_NUM_MAX + 1];
DWORD WINAPI WorkerThread(LPVOID lpParam);
DWORD WINAPI AcceptThread(LPVOID lpParam);
int parserMsg(SOCKET s, char *msg);
SOCKET sListen;
int debug_server_init(void)
{   
	HANDLE hThread;
    WSADATA wsaData;
    //SOCKET  sClient;
    SOCKADDR_IN local;
	//SOCKADDR_IN client;
    int iAddrSize = sizeof(SOCKADDR_IN);
    DWORD dwThreadId;
	DWORD dwAcceptThreadId;
    // Initialize windows socket library
    WSAStartup(0x0202, &wsaData);
    // Create listening socket
    sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 
    // Bind   
    local.sin_family = AF_INET;
    local.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
    local.sin_port = htons(PORT);
    bind(sListen, (sockaddr*)&local, sizeof(SOCKADDR_IN));
    // Listen
    listen(sListen, 3);
    // Create worker thread
    CreateThread(NULL, 0, WorkerThread, NULL, 0, &dwThreadId);
	
	hThread = CreateThread(NULL, 0, AcceptThread, NULL, 0, &dwAcceptThreadId);
	//WaitForSingleObject(hThread,  INFINITE);
    return 0;
}   
DWORD WINAPI AcceptThread(LPVOID lpParam)
{
	SOCKET  sClient;
	SOCKADDR_IN client;
    int iAddrSize = sizeof(SOCKADDR_IN);
	while (TRUE)
    {
        // Accept a connection   
        sClient = accept(sListen, (sockaddr*)&client, &iAddrSize); 
        printf("Accepted client:%s:%d/n", inet_ntoa(client.sin_addr), ntohs(client.sin_port));
        // Add socket to g_CliSocketArr
        if(g_iTotalConn > CLIENT_SOCKET_NUM_MAX - 1)
        {
            continue;
        }
        g_CliSocketArr[g_iTotalConn++] = sClient;
    }
}
DWORD WINAPI WorkerThread(LPVOID lpParam)
{
    int i;
    fd_set fdread;
    int ret;
    struct timeval tv = {1, 0};
    while (TRUE)
    {
		char szMessage[MSGSIZE] = {0};
        FD_ZERO(&fdread);
        for (i = 0; i < g_iTotalConn; i++)
        {
            FD_SET(g_CliSocketArr[i], &fdread);
        }
        // We only care read event
        ret = select(0, &fdread, NULL, NULL, &tv);
        if (ret == 0)
        {
            // Time expired
            continue;   
        }
        for (i = 0; i < g_iTotalConn; i++)
        {
            if (FD_ISSET(g_CliSocketArr[i], &fdread))
            {
                // A read event happened on g_CliSocketArr
                ret = recv(g_CliSocketArr[i], szMessage, MSGSIZE, 0);
                if (ret == 0 || (ret == SOCKET_ERROR && WSAGetLastError() == WSAECONNRESET))
                {
                    // Client socket closed
                    printf("Client socket %d closed./n", g_CliSocketArr[i]);
                    closesocket(g_CliSocketArr[i]);
                    if (i < g_iTotalConn-1)
                    {
                        g_CliSocketArr[i--] = g_CliSocketArr[--g_iTotalConn];
                    }
                }
                else
                {
                    // We reveived a message from client
					if(strlen(szMessage) > 0)
					{
						printf("receive a messagexxxx: %s\n", szMessage);
					}
					//char buf[100] = "hello word.\n";
                    //send(g_CliSocketArr[i], buf, strlen(buf), 0);
					parserMsg(g_CliSocketArr[i], szMessage);
                }
            }
        }
    }
}

int parserMsg(SOCKET s, char *msg)
{
	if(NULL == msg)
	{
		return ERROR;
	}
	int i=0;
	int word_num = 0;
	char *p;
    char *delims=" ";
	char *next_token = NULL;
	char localBuf[MAX_CMD_WORD_NUM][MAX_CMD_WORD_LEN] = {0};
    p=strtok_s(msg, delims, &next_token);
    while(p!=NULL)
	{
       strcpy_s(localBuf[word_num++], p);
       p=strtok_s(NULL, delims, &next_token);
    }
    for(i=0; i<word_num; i++)
	{
		printf("parser result localBuf[%d]:%s\n", i, localBuf[i]);
	}
	if(0 == strcmp("clear", strlwr(localBuf[0])))
	{
		for(i=0; i<LOCATION_SYSTEM_BRANCH_MAX; i++)
		{
		    LocationSystemCount[i] = 0;
		}
	}
	if((0 == strcmp("show", strlwr(localBuf[0]))) && (0 == strcmp("count", strlwr(localBuf[1]))))
	{
		printf("Show data collect.\n");
		
		//send(s, resp, strlen(resp), 0);
		for(i=0; i<LOCATION_SYSTEM_BRANCH_MAX; i++)
		{
		    if(LocationSystemCount[i] > 0)
		    {
		        char resp[100] = {0};
		        sprintf(resp, "LocationSystemCount[%d]:%d ", i, LocationSystemCount[i]);
				send(s, resp, strlen(resp), 0);
		    }
		}
	}
	if((0 == strcmp("show", strlwr(localBuf[0]))) && (0 == strcmp("time", strlwr(localBuf[1]))))
	{
		//printf("Show 1 min data collect.\n");
		int time = atoi(strlwr(localBuf[2]));
		char resp_tmp[100] = {0};
		sprintf(resp_tmp, "Wait %d min data collect.\n", time);
		send(s, resp_tmp, strlen(resp_tmp), 0);
		
		for(i=0; i<LOCATION_SYSTEM_BRANCH_MAX; i++)
		{
		    LocationSystemCount[i] = 0;
		}
		Sleep(time*60*1000);
		for(i=0; i<LOCATION_SYSTEM_BRANCH_MAX; i++)
		{
		    if(LocationSystemCount[i] > 0)
		    {
		        char resp[100] = {0};
		        sprintf(resp, "LocationSystemCount[%d]:%d", i, LocationSystemCount[i]);
				send(s, resp, strlen(resp), 0);
		    }
		}
	}
	return OK;
}