/*
 * message_list.c
 *
 *  Created on: Oct 9, 2018
 *      Author: zgh
 */

#undef DEBUG

#include "message_list.h"


#define SEND_LIST_SIZE 100

#define list_init(ptr) do {                \
        (ptr)->next = (ptr);                    \
        (ptr)->prev = (ptr);                    \
    } while (0)

static pthread_mutex_t mutex[SEND_LIST_DEPTH];
static list_t send_list[SEND_LIST_DEPTH];
//static pthread_mutex_t list_mutex;

void msg_list_init(void)
{
	int i;
//	pthread_mutex_init(&list_mutex,0);
	for(i = 0; i < SEND_LIST_DEPTH; i++)
	{
        pthread_mutex_init(&mutex[i],NULL);
        list_init(&send_list[i]);
    }
}


int list_size(send_type_t type)
{
	msg_list_t *tmp;
	int i = 0;
    pthread_mutex_lock(&mutex[type]);
    list_for_each_entry(tmp,&send_list[type],list)
	{
		i++;
	}
    pthread_mutex_unlock(&mutex[type]);
	return i;
}


int msg_timeout_del(send_type_t type)
{
	msg_list_t *tmp;
	time_t curr_time = time(NULL);
    if(type >= SEND_LIST_DEPTH)return -1;
    pthread_mutex_lock(&mutex[type]);
	while(!list_empty(&send_list[type]))
	{
		tmp = list_get_first(&send_list[type], msg_list_t, list);
		if(curr_time > tmp->times)
		{
//			log_debug("queue del :[%d.%d] code %02X",tmp->addr.a,tmp->addr.b,tmp->code);
//			log_hex(&g_default_mt,tmp->data,tmp->len);
			list_del(&tmp->list);
			free(tmp);

		}
	}
    pthread_mutex_unlock(&mutex[type]);
    return 0;
}

int msg_get_compare(send_type_t type,	lora_addr_t addr,exp_lora_msg_t *pram)
{
    int ret = 0;
    msg_list_t *tmp = NULL;
    if(type >= SEND_LIST_DEPTH)return -1;
    if(!pram)return -1;
    int retry = 200;//最多遍历200条历史数据
    time_t curr_time = time(NULL);
//    dy_syslog(LOG_INFO,"********* while fetch delay msg ********");
    pthread_mutex_lock(&mutex[type]);
    while(!list_empty(&send_list[type]) && retry--)
    {
        if(addr.b == tmp->addr.b)//TODO 追加超时回收
        {

            memcpy(&pram->addr,&tmp->addr,sizeof(tmp->addr));
            memcpy(&pram->code,&tmp->code,sizeof(tmp->code));
            memcpy(pram->data,tmp->data,tmp->len);
            memcpy(&pram->retry,&tmp->retry,sizeof(tmp->retry));
            memcpy(&pram->len,&tmp->len,sizeof(tmp->len));
//			memcpy(&pram->msg,&tmp->msg,sizeof(tmp->msg));

            if(pram->code == 0x50)dy_syslog(LOG_INFO,"nodes dev [--],addr %02x,queue %d",pram->addr.b,type);
//			log_debug("queue get delay:[%d.%d] code %02X",pram->addr.a,pram->addr.b,pram->code);
//			log_hex(&g_default_mt,pram->data,pram->len);
//			log_debug("queue get delay:[%d.%d] code %02X",pram->addr.a,pram->addr.b,pram->code);
            list_del(&tmp->list);
//			log_debug("queue get delay:[%d.%d] code %02X",pram->addr.a,pram->addr.b,pram->code);
            free(tmp);
            ret =1;
            break;
        }
    }
    pthread_mutex_unlock(&mutex[type]);
    return ret;
}
/**功能：读取缓存队列内容
 * 参数：
 * 参数：
 * 返回值：
 */
int msg_get_first(send_type_t type,	exp_lora_msg_t *pram)
{
    //pthread_mutex_lock(&list_mutex);
    msg_list_t *tmp;
    time_t curr_time = time(NULL);
    int ret = 0;
    pthread_mutex_lock(&mutex[type]);
    tmp = list_get_first(&send_list[type], msg_list_t, list);
    if(tmp == NULL )
    {
        pthread_mutex_unlock(&mutex[type]);
        return 0;
    }

    ret = 1;
    if(pram)
    {
        memcpy(&pram->addr,&tmp->addr,sizeof(tmp->addr));
        memcpy(&pram->code,&tmp->code,sizeof(tmp->code));
        memcpy(pram->data,tmp->data,tmp->len);
        memcpy(&pram->retry,&tmp->retry,sizeof(tmp->retry));
        memcpy(&pram->len,&tmp->len,sizeof(tmp->len));
        memcpy(&pram->times,&tmp->times,sizeof(tmp->times));
    }

    list_del(&tmp->list);
    free(tmp);
    pthread_mutex_unlock(&mutex[type]);
    return ret;
}

int msg_add_tail(send_type_t type,	exp_lora_msg_t *pram)
{

	msg_list_t *tmp = malloc(sizeof(msg_list_t));
    pthread_mutex_lock(&mutex[type]);
	list_add_tail(&tmp->list,&send_list[type]);
	tmp->addr = pram->addr;
	tmp->code = pram->code;
	tmp->len = pram->len;
	tmp->retry = pram->retry;
//	tmp->msg = pram->msg;
	if(pram->times)		tmp->times = time(NULL) + pram->times;
	else tmp->times = 0;
	memcpy(tmp->data,pram->data,pram->len);
//	log_debug("queue add tail:[%d.%d] code %02X, retry %d, UTC %d",pram->addr.a,pram->addr.b,pram->code,pram->retry,pram->times);
//	log_hex(&g_default_mt,pram->data,pram->len);
    pthread_mutex_unlock(&mutex[type]);
	return 0;
}


