#include<stdio.h>
#include"com_api.h"

#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/shm.h>
#include "cJSON.h"
#include "kk_product.h"
#include "kk_tsl_common.h"
#include "kk_dm_api.h"



void mid_cb(void* data, int len){
	if (data != NULL){
		printf("app2mid_cb: %s RECEIVED \r\n", data); 
        char *out;cJSON *json, *topic, *payload;
        int res;

    	json=cJSON_Parse(data);
    	if (!json) {
            printf("Error before: [%s]\n","cJSON_Parse");
        }
    	else
    	{
            topic = cJSON_GetObjectItem(json, "topic");
            payload = cJSON_GetObjectItem(json, "payload");
            printf("mid_cb topic: [%s] ,payload= %s  \n",topic->valuestring,payload->valuestring );
            if (strcmp(payload->valuestring, "addsub")==0){
                //kk_mid_subdev_add("a1OYuSallan","allanWno8yDdsjCX15iq","");
            }else{
                void* buf = malloc(len);
                memcpy(buf, data, len);
                int res = dm_queue_msg_insert((void *)buf);
                if (res != SUCCESS_RETURN) {
                    free(buf);
                    //return FAIL_RETURN;
                }
            
                //kk_tsl_service_property_set(topic->valuestring, payload->valuestring, strlen(payload->valuestring), NULL);
            }
            char mac[DEVICE_MAC_MAXLEN];
            res =dm_mgr_search_mac_by_topic(topic->valuestring, mac);
            if (res != SUCCESS_RETURN) {
                return;
            }
            printf("dm_mgr_search_mac_by_topic mac: %s  \r\n", mac);
            
            cJSON * jsonplay=cJSON_Parse(payload->valuestring);
            cJSON_AddStringToObject(jsonplay, "mac", mac);
            void* out =  cJSON_Print(jsonplay);
            kk_ipc_send(IPC_MID2PLAT, out, strlen(out));
            free(out);
            cJSON_Delete(jsonplay);
            cJSON_Delete(json);
            
	    }
	    
        
	}
}

void mid2p_cb(void* data, int len){
	if (data != NULL){
		printf("mid2plat_cb: %s RECEIVED \r\n", data);
		void* buf = malloc(len);
        memcpy(buf, data, len);
        int res = dm_queue_msg_insert2((void *)buf);
        if (res != SUCCESS_RETURN) {
            free(buf);
            return ;
        }
		
        //kk_ipc_send(IPC_MID2APP, data, len);
	}
}

void kk_platMsg_handle(void* data){
    
    char *out;
    int res = 0;
    cJSON *json, *method, *params;
    
    json=cJSON_Parse(data);
	if (!json) {
        printf("Error before: [%s]\n","cJSON_Parse");
    }
	else{
        method = cJSON_GetObjectItem(json, "method");
        if (method != NULL && strcmp(method->valuestring, "thing.topo.add")==0){
                cJSON *jsonPay, *proType, *proCode, *mac;
                params = cJSON_GetObjectItem(json, "params");
                jsonPay =cJSON_Parse(params->valuestring);
                
                if (!jsonPay) {
                    printf("Error before: [%s]\n","cJSON_Parse");
                }else{
                    proType = cJSON_GetObjectItem(jsonPay, "productType");
                    proCode = cJSON_GetObjectItem(jsonPay, "productCode");
                    mac = cJSON_GetObjectItem(jsonPay, "mac");
                    printf("productType productCode : [%s][%s]\n",proType, proCode);
                    kk_set_tsl_by_productKey(proCode->valuestring,"model.json");
                    kk_mid_subdev_add(proType->valuestring,proCode->valuestring,"", mac->valuestring);
                    cJSON_Delete(jsonPay);
                }
                
        }else if (method != NULL && strcmp(method->valuestring, "thing.event.property.post")==0){
            cJSON *mac;
            mac = cJSON_GetObjectItem(json, "mac");
            
            
            //kk_tsl_service_property_set(topic->valuestring, data, strlen(data), NULL);
            
        }else{
            printf("kk_platMsg_handle data: [%s]\n",data);
        
            //kk_tsl_service_property_set(topic->valuestring, payload->valuestring, strlen(payload->valuestring), NULL);
        }
        cJSON_Delete(json);
   }
}

void kk_platMsg_dispatch(void)
{
    int count = 0;
    void *data = NULL;

    while (CONFIG_DISPATCH_QUEUE_MAXLEN == 0 || count++ < CONFIG_DISPATCH_QUEUE_MAXLEN) {

        if (dm_queue_msg_next2(&data) == SUCCESS_RETURN) {
            //dm_queue_msg_t *msg = (dm_queue_msg_t *)data;
            printf("kk_handle_platMsg_dispatch get call \n");
            if (kk_platMsg_handle) {
                kk_platMsg_handle( data);
            }

            
            free(data);
            data = NULL;
        } else {
            break;
        }
    }
}



#define MYPORT  5555
#define BUFFER_SIZE 1024

void test_tcp(){

    ///定义sockfd
    int sock_cli = socket(AF_INET,SOCK_STREAM, 0);
 
    ///定义sockaddr_in
    struct sockaddr_in servaddr;
    memset(&servaddr, 0, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(MYPORT);  ///服务器端口
    servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");  ///服务器ip
 
    ///连接服务器，成功返回0，错误返回-1
    if (connect(sock_cli, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0)
    {
        perror("connect");
        exit(1);
    }
 
    char sendbuf[BUFFER_SIZE]={0};
    char recvbuf[BUFFER_SIZE];
    //printf("midd: %s send \r\n", sendbuf); 
    //send(sock_cli, sendbuf, strlen(sendbuf),0);
    while (fgets(sendbuf, sizeof(sendbuf), stdin) != NULL)
    {
        printf("midd: %s send \r\n", sendbuf); 
        send(sock_cli, sendbuf, strlen(sendbuf),0); ///发送
        if(strcmp(sendbuf,"exit\n")==0)
            break;
        //printf("midd: %s send \r\n", sendbuf); 
        recv(sock_cli, recvbuf, sizeof(recvbuf),0); ///接收
        fputs(recvbuf, stdout);
 
        memset(sendbuf, 0, sizeof(sendbuf));
        memset(recvbuf, 0, sizeof(recvbuf));
    }
 
    close(sock_cli);
    
}

time_t getSysTime(){
    time_t t;  
    t = time(NULL);  
    return t;

}

typedef struct {
    int auto_add_subdev;
    int master_devid;
    int cloud_connected;
    int master_initialized;
    int subdev_index;
    int permit_join;
    void *g_mid_dispatch_thread;
    int g_mid_dispatch_thread_running;
} mid_ctx_t;
#define MID_YIELD_TIMEOUT_MS (200)


static mid_ctx_t g_mid_ctx;

static mid_ctx_t *kk_mid_get_ctx(void)
{
    return &g_mid_ctx;
}

extern void IOT_Linkkit_Yield(int timeout_ms);
void *mid_dispatch_yield(void *args)
{
    mid_ctx_t *mid_ctx = kk_mid_get_ctx();

    while (mid_ctx->g_mid_dispatch_thread_running) {
        IOT_Linkkit_Yield(MID_YIELD_TIMEOUT_MS);
    }

    return NULL;
}
static int kk_set_product_info(void)
{
	HAL_SetProduct_Type(PRODUCT_TPYE);
	HAL_SetProduct_Code(PRODUCT_CODE);	
	kk_set_tsl_by_productKey(PRODUCT_TPYE,"gateway.json");
	return 0;
}

int main(const int argc, const char **argv)
{
		
        int res = 0;
        mid_ctx_t *mid_ctx = kk_mid_get_ctx();

        
        memset(mid_ctx, 0, sizeof(mid_ctx_t));
		
		kk_set_product_info();
        kk_tsl_api_init();
        kk_ipc_init(IPC_MID2APP, mid_cb);
        kk_ipc_init(IPC_MID2PLAT, mid2p_cb);
		dm_mgr_init();

        //DB_Init();
        //test_tcp();
        /* when Connect to app and platfrom */
        /*do {
            res = IOT_Linkkit_Connect(user_example_ctx->master_devid);
            if (res < 0) {
                EXAMPLE_TRACE("IOT_Linkkit_Connect failed, retry after 5s...\n");
                HAL_SleepMs(5000);
            }
        } while (res < 0);*/
        kk_init_dmproc();
        mid_ctx->g_mid_dispatch_thread_running = 1;
        res = pthread_create(&mid_ctx->g_mid_dispatch_thread, NULL, mid_dispatch_yield, NULL);
        if (res < 0) {
            printf("HAL_ThreadCreate Failed\n");
            IOT_Linkkit_Close(mid_ctx->master_devid);
            return -1;
        }
        char buf[100] = {0};
        int ct = 0;
		for (;;) {
                usleep(4000000);
                if (ct == 0){
                    ct =1;

                    kk_set_tsl_by_productKey("a1OYuSallan","model.json");
                    kk_mid_subdev_add("a1OYuSallan","allanWno8yDdsjCX15iq","","aabbccddeeff1122");
                }

                /*memset(buf, 0, 100);
                sprintf(buf , "send data app time = %d\n", getSysTime());
                printf("M2A: %s", buf);
                kk_ipc_send(IPC_MID2APP, buf, strlen(buf)+1);
                memset(buf, 0, 100);
                sprintf(buf, "send data to plat time = %d\n", getSysTime());
                printf("M2P: %s", buf);
                kk_ipc_send(IPC_MID2PLAT, buf, strlen(buf) + 1);*/
        }
}

