#include <pthread.h>
#include "kk_lan_queue.h"
#include "kk_log.h"

static lan_queue_s g_lan_queue[LAN_QUEUE_END];

static lan_queue_s *_lan_queue_get_ctx(LAN_QUEUE_ENUM ix)
{
	return &g_lan_queue[ix];
}

static void _lan_queue_lock(LAN_QUEUE_ENUM ix)
{
	int err_num;
	lan_queue_s *ctx = _lan_queue_get_ctx(ix);
	
	if (0 != (err_num = pthread_mutex_lock((pthread_mutex_t *)ctx->mutex))) {
		WARNING_PRINT("\nlock queue mutex[%d] failed: - '%s' (%d)\n",ix,strerror(err_num), err_num);
	}
}
static void _lan_queue_unlock(LAN_QUEUE_ENUM ix)
{
	int err_num;
	lan_queue_s *ctx = _lan_queue_get_ctx(ix);
	
	if (0 != (err_num = pthread_mutex_unlock((pthread_mutex_t *)ctx->mutex))) {
		WARNING_PRINT("unlock queue mutex[%d] failed - '%s' (%d)\n",ix, strerror(err_num), err_num);
	}
}


static int _lan_queue_init(LAN_QUEUE_ENUM ix,int max_size)
{
	int err_num;
	lan_queue_s *ctx = _lan_queue_get_ctx(ix);

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

	ctx->mutex = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t));
	if (ctx->mutex == NULL) {
		return -1;
	}
	
	if (0 != (err_num = pthread_mutex_init(ctx->mutex, NULL))) {
		WARNING_PRINT("\ninit queue mutex[%d] failed\n",ix);
		free(ctx->mutex);
		return -2;
	}
	
	ctx->max_size = max_size;
	INIT_LIST_HEAD(&ctx->list);
	INFO_PRINT("\nlan queue[%d] init success~~~\n",ix);

	return 0;
}



int lan_queue_init(void)
{
	return _lan_queue_init(NODE_MAP,LAN_QUEUE_SIZE(1));
}
void lan_queue_deinit(void)
{
	//do it;
}


int lan_queue_enqueue(LAN_QUEUE_ENUM ix,void *data)
{
	lan_queue_s *ctx = _lan_queue_get_ctx(ix);
	lan_queue_msg_s *node = NULL;

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

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

	node = malloc(sizeof(lan_queue_msg_s));

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


	node->data = data;

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

	_lan_queue_unlock(ix);

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

	return 0;
}

int lan_queue_dequeue(LAN_QUEUE_ENUM ix,void **data)
{
	lan_queue_s *ctx = _lan_queue_get_ctx(ix);
	lan_queue_msg_s *node = NULL;



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

	_lan_queue_lock(ix);

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

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

	ctx->size--;

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

	_lan_queue_unlock(ix);

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

























