//=========kk=============
#include "com_api.h"

#define APP2MID "ipc:///tmp/app2mid.ipc"
#define PLAT2MID "ipc:///tmp/plat2mid.ipc"

typedef struct {
    int n;          //nanomsg socket
    int s;          //nanomsg recieve fd
}nanomsg_info_t;
  
typedef struct {
    nanomsg_info_t ba;
}Bloop_ctrl_t;
Bloop_ctrl_t Bloop_ctrl;
static struct ev_io g_watcher;
struct ev_loop* gloop;

ipc_cb* g_cb = NULL;

static void watcher_cb (struct ev_loop *loop ,struct ev_io *w, int revents)
{

	void *user_data = ev_userdata(loop);
    Bloop_ctrl_t *Bloop_ctrl = (Bloop_ctrl_t *)user_data;
    uint8_t *dat = NULL;
    uint32_t bytes = nn_recv(Bloop_ctrl->ba.n, &dat, NN_MSG, NN_DONTWAIT);
    if (bytes <= 0) {
        return;
    }
    printf("watcher_cb:%s recived\r\n\r\n", (char *)dat);
	if (g_cb != NULL){
		g_cb((void *)dat);
	}
    nn_freemsg(dat);
}


struct ev_loop* __loop_init(Bloop_ctrl_t *loop_ctrl)
{
    
    struct ev_loop *loop = ev_loop_new(EVBACKEND_EPOLL);
    if (NULL == loop) {
        printf("create loop failed\r\n");
        return NULL;
    }
    ev_io_init (&g_watcher, watcher_cb, loop_ctrl->ba.s, EV_READ);
    ev_io_start (loop, &g_watcher);
    return loop;
}


int __nanomsg_init(Bloop_ctrl_t *Bloop_ctrl, ipc_type type)
{
    Bloop_ctrl->ba.n = nn_socket(AF_SP, NN_PAIR);
	printf("__nanomsg_initBloop_ctrl->ba.n=%d \r\n",Bloop_ctrl->ba.n);
    if (Bloop_ctrl->ba.n < 0) {
        return -1;
    }

	switch (type) {
        case IPC_APP2MID:{
            if (nn_connect(Bloop_ctrl->ba.n, APP2MID) < 0) {
		        return -1;
		    }
        }
        break;
		case IPC_PLAT2MID: {
            if (nn_connect(Bloop_ctrl->ba.n, PLAT2MID) < 0) {
		        return -1;
		    }
        }
        break;
		case IPC_MID2APP: {
            if (nn_bind(Bloop_ctrl->ba.n, APP2MID) < 0) {
		        return -1;
		    }
        }
        break;
		case IPC_MID2PLAT: {
            if (nn_bind(Bloop_ctrl->ba.n, PLAT2MID) < 0) {
		        return -1;
		    }
        }
        break;
        default: {
        }
        break;
    } 
   
    size_t size = sizeof(size_t);
    if (nn_getsockopt(Bloop_ctrl->ba.n, NN_SOL_SOCKET, NN_RCVFD, (char *)&Bloop_ctrl->ba.s, &size) < 0) {
        return -1;
    }
    return 0;
}




/*=================================
*  TODO: only one methd pair
*
*
==================================*/
void loop_thread(void *arg){
	gloop = __loop_init(&Bloop_ctrl);
    if (NULL == gloop) {
        printf("gloop init failed\r\n");
        return ;
    }
	
    ev_set_userdata(gloop, &Bloop_ctrl);
    ev_run (gloop, 0);
	
}
int kk_ipc_init(ipc_type type, ipc_cb cb)
{
	pthread_t pb;
	if (g_cb != NULL){

		printf("ipc has been inited!\r\n");
		return -1;
	}
	
    if (__nanomsg_init(&Bloop_ctrl, type) < 0) {
        printf("nanomsg init failed\r\n");
        return -1;
    }

	if (0 != pthread_create(&pb, NULL, loop_thread, NULL)) {
        printf("create pthread B failed\r\n");
        return -1;
    }
	g_cb  = cb;
    return 0;
	
}

int kk_ipc_dinit()
{
	if (Bloop_ctrl.ba.n > -1){
		nn_shutdown(Bloop_ctrl.ba.n, 0);
	}

	ev_io_stop(gloop, &g_watcher);

    ev_break(gloop,EVBREAK_ALL);
	g_cb = NULL;
	return 0;

}

int kk_ipc_send(void* data)
{
	//printf("kk_ipc_send 11111111\r\n");
	if (data != NULL){
		printf("kk_ipc_send data= %s\r\n", data);
		char* buf = nn_allocmsg(strlen(data)+1, 0);
		memcpy(buf, data,strlen(data)+1);
		nn_send(Bloop_ctrl.ba.n, &buf, NN_MSG, NN_DONTWAIT);
		//printf("kk_ipc_send: RECEIVED \"%s\"\n", data); 
	}

	return 0;

}
