#include<stdio.h>
#include <string.h>
#include <sys/select.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <errno.h>
#include <stdlib.h>
#include <pthread.h>
#include <signal.h>
#include "kk_login_handle.h"
#include "kk_data_handle.h"

#define LISTEN_MAX 5
#define BUF_SIZE 1500

typedef struct {
	int socketfd;
	char ip[18];	
} kk_clientInfo_t;
static kk_clientInfo_t s_ConnInfo[LISTEN_MAX] = {0};
static pthread_mutex_t data_mutex;
fd_set fds;

int kk_send_data_to_sdk(char *buf)
{
	char *tmpBuf = NULL;   
	int i = 0;
	tmpBuf = calloc(strlen(buf) + 4,1);
	if(tmpBuf == NULL){
		return -1;
	}
	strcat(tmpBuf,"!");
	strcat(tmpBuf,buf);
	strcat(tmpBuf,"$");
	INFO_PRINT("tmpBuf:%s\n",tmpBuf);
	for(i = 0; i < LISTEN_MAX; i++){
		if(s_ConnInfo[i].socketfd != -1){
			send(s_ConnInfo[i].socketfd, tmpBuf, strlen(tmpBuf), 0);
		}
	}

	free(tmpBuf); 
	return 0;
}
static int _kk_handle_data(char *buf,int sockfd){
	char *pStart = NULL,*pEnd = NULL;  
	char tmpBuf[BUF_SIZE] = {0};     
	cJSON *json; 
	if(buf == NULL){
		return -1;
	}
	printf("[%s][%d]\n",__FUNCTION__,__LINE__);
	pStart = strstr(buf, "!");
	pEnd = strstr(buf, "$");  
	if(pStart != NULL && pEnd != NULL){
		memset(tmpBuf,0x0,sizeof(tmpBuf));
		memcpy(tmpBuf,pStart+1,(pEnd - pStart - 1));
	}
	json=cJSON_Parse(tmpBuf);
	if (!json) {
		WARNING_PRINT("Error before: [%s]\n","cJSON_Parse");
	}else{
		printf("[%s][%d]\n",__FUNCTION__,__LINE__);
		kk_data_handle(json,sockfd);
	
		printf("[%s][%d]\n",__FUNCTION__,__LINE__);
		cJSON_Delete(json);
		printf("[%s][%d]\n",__FUNCTION__,__LINE__);
	}
}

static void PrintMesg(int i , char buf[])
{
    printf("fd : %d, msg: %s\n", i , buf);
}

void *TCP_Analyzer(void *pPara)
{
	char Buf[BUF_SIZE] = {0};
	ssize_t Size  = 0;
	int index = 0;
	unsigned char *pReceiveData = NULL;
	int ReceiveLen = 0;

	if (NULL == pPara)
	{
		ERROR_PRINT("TCP_Analyzer: TCP_Analyzer Failed!\n");
		return NULL;
	}

	index = *(int *)pPara;
	printf("index:%d\n",*(int *)pPara);
	if(index < 0 || index >= LISTEN_MAX)
	{
		ERROR_PRINT("TCP_Analyzer:Get pConnfd Failed \n" );
		return NULL;
	}

	while(1)
	{
		memset(Buf, '\0', sizeof(Buf));
		Size = read(s_ConnInfo[index].socketfd, Buf,sizeof(Buf) );
		if (Size <= 0) //没有接收到数据，关闭描述符，释放在TCPServer申请的空间
		{
		
			printf("Size=%d,errno=%d",Size,errno);
			ERROR_PRINT("TCP_Analyzer:remote client close:%d\n",s_ConnInfo[index].socketfd );
			pthread_mutex_lock(&data_mutex);
			close(s_ConnInfo[index].socketfd);
			s_ConnInfo[index].socketfd = -1;
			memset(s_ConnInfo[index].ip,0x0,sizeof(s_ConnInfo[index].ip));
			pthread_mutex_unlock(&data_mutex);

			return NULL;
		}
		else
		{
			DEBUG_PRINT("TCP_Analyzer:%s,%d\n",Buf,(int)Size);
			_kk_handle_data(Buf,s_ConnInfo[index].socketfd);
			printf("[%s][%d] TCP_Analyzer end.\n",__FUNCTION__,__LINE__);
		}
	}
	return NULL;
}
static int kk_check_is_connect(char *ip){
	int i = 0;
	if(ip == NULL){
		return -1;
	}
	for(i =  0; i < LISTEN_MAX; i ++){
		if(s_ConnInfo[i].socketfd != -1 && strcmp(s_ConnInfo[i].ip,ip) == 0){
			return 1;
		}
	}
	return 0;
}
void *TCPServer()
{
	pthread_t threadID = 0;
	struct sockaddr_in Server;
	struct sockaddr_in Client;
	int Listenfd = 0;
	int i = 0;
	int j = 0;
	int yes = 1;
	int index = 0;
	int Connfd = 0;
	int ret = 0;
	char clientIp[18] = {0};
	socklen_t len = 0;

	//char logMessage[128] = {0};
	pthread_attr_t attr;
	pthread_attr_init(&attr);
	pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);

	Listenfd = socket(AF_INET, SOCK_STREAM, 0);
	if (Listenfd < 0)
	{
		perror("socket");
		pthread_attr_destroy(&attr);//线程属性销毁
		return NULL;
	}
	DEBUG_PRINT("TCPServer:create socket success\n");
	setsockopt(Listenfd, SOL_SOCKET, SO_REUSEADDR, &yes ,sizeof(int));// 允许IP地址复用
	bzero(&Server, sizeof(Server));
	Server.sin_family = AF_INET;
	Server.sin_port = htons(SERVER_LISTEN_PORT);
	Server.sin_addr.s_addr = htonl(INADDR_ANY);

	if (bind(Listenfd, (struct sockaddr*)&Server, sizeof(Server)) < 0)
	{
		perror("bind");
		close(Listenfd);
		pthread_attr_destroy(&attr);//线程属性销毁
		return NULL;
	}
	DEBUG_PRINT("TCPServer:bind socket success\n");

	if (listen(Listenfd, LISTEN_MAX) < 0)
	{
		perror("listen");
		close(Listenfd);
		pthread_attr_destroy(&attr);//线程属性销毁
		return NULL;
	}
	DEBUG_PRINT("TCPServer:listen socket success\n");

	while (1)
	{
		//index = -1;
		FD_ZERO(&fds);//描述符集合初始化

		FD_SET(Listenfd,&fds);
		struct timeval timeout = {1, 0};
		ret = select(Listenfd + 1, &fds,NULL, NULL, &timeout );
		if(ret <= 0){
			DEBUG_PRINT("TCPServer:TCP receiving nothing......\n");
			//break;
		}else{
			printf("[%s][%d]\n",__FUNCTION__,__LINE__);
			if (FD_ISSET(Listenfd, &fds))
			{
				len = sizeof(Client);
				bzero(&Client, len);
				Connfd = accept(Listenfd, (struct sockaddr*)&Client,&len );
				printf("addr:%s\n",inet_ntoa(Client.sin_addr));
				printf("[%s][%d]Connfd:%d\n",__FUNCTION__,__LINE__,Connfd);
				//若有新的连接
				if (Connfd != -1)
				{
					memset(clientIp,0x0,sizeof(clientIp));
					strcpy(clientIp,inet_ntoa(Client.sin_addr));
					if(kk_check_is_connect(clientIp) == 1){
						DEBUG_PRINT("already connect!!!\n");
						continue;
					}
					for(i =  0; i < LISTEN_MAX; i ++){
						if(s_ConnInfo[i].socketfd != -1){
							if(i == LISTEN_MAX-1){
								DEBUG_PRINT("more then max client!!!\n");
							}
							continue;
						}else{
							pthread_mutex_lock(&data_mutex);
							s_ConnInfo[i].socketfd = Connfd;
							memcpy(s_ConnInfo[i].ip,clientIp,strlen(clientIp));
							index = i;
							printf("index:%d\n",index);
							pthread_mutex_unlock(&data_mutex);
							break;
						}
					}
					ret = pthread_create(&threadID, &attr, TCP_Analyzer, &index);
					if(0 != ret)
					{
						DEBUG_PRINT("TCPServer: TCP_Analyzer build Fail!\n");
						FD_CLR(Listenfd, &fds);// 清除 fds中相应的文件描述符
						close(Listenfd);
						pthread_attr_destroy(&attr);//线程属性销毁
						return NULL;
					}

				}
			}
		}

	}
	FD_CLR(Listenfd, &fds);// 清除 fds中相应的文件描述符
	close(Listenfd);
	pthread_attr_destroy(&attr);//线程属性销毁
	return NULL;
}

int kk_login_init()
{
	int ret = 0;
	int i = 0;
	pthread_t threadID = 0;

	DEBUG_PRINT("kk_login_init Init OK!\n");
	for(i =  0; i < LISTEN_MAX; i ++){
		s_ConnInfo[i].socketfd = -1;
		memset(s_ConnInfo[i].ip,0x0,sizeof(s_ConnInfo[i].ip));
	}
	if (pthread_mutex_init(&data_mutex, NULL) != 0) {
		ERROR_PRINT("pthread_mutex_init kk_login_init err\n");
		return -1;
	}
	ret = pthread_create(&threadID, NULL, TCPServer, NULL);
	if(0 != ret)
	{
		ERROR_PRINT("TCPServer: TCPServer build Fail!\n");
		return -1;
	}
	return 0;
}
