#include <pthread.h>
#include "kk_ncp_queue.h"
#include "app/framework/include/af.h"



static ncp_queue_s g_ncp_queue[GET_PROPERTY];

static ncp_queue_s *_ncp_queue_get_ctx(NCP_QUEUE_ENUM ix)
{
	return &g_ncp_queue[ix];
}

static void _ncp_queue_lock(NCP_QUEUE_ENUM ix)
{
	int err_num;
	ncp_queue_s *ctx = _ncp_queue_get_ctx(ix);
	
	if (0 != (err_num = pthread_mutex_lock((pthread_mutex_t *)ctx->mutex))) {
		UTIL_LOG_WARNING("\nlock queue mutex[%d] failed: - '%s' (%d)\n",ix,strerror(err_num), err_num);
	}
}
static void _ncp_queue_unlock(NCP_QUEUE_ENUM ix)
{
	int err_num;
	ncp_queue_s *ctx = _ncp_queue_get_ctx(ix);
	
	if (0 != (err_num = pthread_mutex_unlock((pthread_mutex_t *)ctx->mutex))) {
		UTIL_LOG_WARNING("unlock queue mutex[%d] failed - '%s' (%d)\n",ix, strerror(err_num), err_num);
	}
}


static int _ncp_queue_init(NCP_QUEUE_ENUM ix,int max_size)
{
	int err_num;
	ncp_queue_s *ctx = _ncp_queue_get_ctx(ix);

	memset(ctx, 0, sizeof(ncp_queue_s));

	ctx->mutex = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t));
	if (ctx->mutex == NULL) {
		UTIL_LOG_WARNING("\nmalloc queue mutex[%d] failed: - '%s' (%d)\n",ix, strerror(err_num), err_num);
		return -1;
	}
	
	if (0 != (err_num = pthread_mutex_init(ctx->mutex, NULL))) {
		UTIL_LOG_WARNING("\ninit queue mutex[%d] failed\n",ix);
		free(ctx->mutex);
		return -2;
	}
	
	ctx->magic = KK_NCP_QUEUE_MAGIC;
	ctx->max_size = max_size;
	INIT_LIST_HEAD(&ctx->list);
	UTIL_LOG_INFO("\nncp queue[%d] init success~~~\n",ix);

	return 0;
}



int ncp_queue_init(void)
{
	_ncp_queue_init(REV_MSG,NCP_QUEUE_SIZE(1));
	_ncp_queue_init(GET_PROPERTY,NCP_QUEUE_SIZE(2));
}
void ncp_queue_deinit(void)
{
	//do it;
}


int ncp_queue_enqueue(NCP_QUEUE_ENUM ix,void *data)
{
	ncp_queue_s *ctx = _ncp_queue_get_ctx(ix);
	ncp_queue_msg_s *node = NULL;

	if(ctx->magic!=KK_NCP_QUEUE_MAGIC){
		UTIL_LOG_WARNING("\nenqueue-[%d] fail,queue-[%d] not init!!!\n",ix);
		return -1;
	}

	if (data == NULL) {
		UTIL_LOG_DBG("\nenqueue-[%d] fail,data is NULL!!!\n",ix);
		return -2;
	}

	_ncp_queue_lock(ix);
	UTIL_LOG_DBG("\nlist size: %d, max size: %d\n", ctx->size, ctx->max_size);
	if (ctx->size >= ctx->max_size) {
		UTIL_LOG_DBG("\nenqueue-[%d] fail,queue full!!!\n",ix);
		_ncp_queue_unlock(ix);
		return -3;
	}

	node = malloc(sizeof(ncp_queue_msg_s));

	if (node == NULL) {
		UTIL_LOG_DBG("\nenqueue-[%d] fail,node is NULL!!!\n",ix);
		_ncp_queue_unlock(ix);
		return -4;
	}
	memset(node, 0, sizeof(ncp_queue_msg_s));


	node->data = data;

	INIT_LIST_HEAD(&node->list);
	ctx->size++;
	list_add_tail(&node->list, &ctx->list);

	_ncp_queue_unlock(ix);

	UTIL_LOG_INFO("\nenqueue-[%d] success~~~\n",ix);

	return 0;
}

int ncp_queue_dequeue(NCP_QUEUE_ENUM ix,void **data)
{
	ncp_queue_s *ctx = _ncp_queue_get_ctx(ix);
	ncp_queue_msg_s *node = NULL;

	if(ctx->magic!=KK_NCP_QUEUE_MAGIC){
		return -1;
	}

	if (data == NULL) {
		return -2;
	}

	_ncp_queue_lock(ix);

	if (list_empty(&ctx->list)) {
		_ncp_queue_unlock(ix);
		return -3;
	}

	node = list_first_entry(&ctx->list, ncp_queue_msg_s, list);
	list_del(&node->list);

	ctx->size--;

	*data = node->data;
	free(node);

	_ncp_queue_unlock(ix);

	UTIL_LOG_INFO("\ndequeue queue[%d] success~~~\n",ix);
	return 0;
}
























