#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,"$");
    printf("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(buf);
    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);
        cJSON_Delete(json);
    }    
}

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申请的空间
        {
            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
        {
            printf("TCP_Analyzer:%s,%d\n",Buf,(int)Size);
            _kk_handle_data(Buf,s_ConnInfo[index].socketfd);
        }
    }
    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 == 4){
                                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;
}
