/************************************************************
* Details: 消息队列
* Encode: UTF-8
* Platform: Android & Linux
* Author: R&D 2
* Date: 2018-4-2
************************************************************/
#include <stdlib.h>
#include <unistd.h>
#include <cstring>
#include "gtmessagequeue.h"

GtMessageQueue *GtMessageQueue::_instance = NULL;
pthread_mutex_t GtMessageQueue::_mutex = PTHREAD_MUTEX_INITIALIZER;

GtMessageQueue::GtMessageQueue()
{
    _messageQueue = NULL;
}

GtMessageQueue::~GtMessageQueue()
{
    releaseMessageQueue();
}

GtMessageQueue *GtMessageQueue::instance()
{
    if(_instance == NULL)
    {
        _instance = new GtMessageQueue();
    }
    return _instance;
}

/************************************************************
*功能：插入消息节点到消息队列末尾
*输入：node消息节点
*输出：无
*返回：!=0错误
*/
bool GtMessageQueue::appendNode(stMessageQueue *node)
{
    stMessageQueue *tmpNode = NULL;

    if(node == NULL)
    {
        return false;
    }
    if(_messageQueue == NULL)
    {
        _messageQueue = node;
        _messageQueue->next = NULL;
    }
    else
    {
        tmpNode = _messageQueue;
        while(tmpNode->next != NULL)
        {
            tmpNode = tmpNode->next;
        }
        node->next = NULL;
        tmpNode->next = node;
    }
    return true;
}

/************************************************************
*功能：构建消息队列
*输入：maxSize消息队列最大长度
*输出：无
*返回：true成功
*/
bool GtMessageQueue::initMessageQueue(int maxSize)
{
    int i = 0;
    stMessageQueue *node = NULL;

    for(i = 0; i < maxSize; i++)
    {
        node = (stMessageQueue*)malloc(sizeof(stMessageQueue));
        if(node == NULL)
        {
            return false;
        }
        else
        {
            memset(node, 0, sizeof(stMessageQueue));
            node->next = NULL;
            if(!appendNode(node))
            {
                return false;
            }
        }
    }
    return true;
}

/************************************************************
*功能：释放消息队列
*输入：无
*输出：无
*返回：无
*/
void GtMessageQueue::releaseMessageQueue()
{
    stMessageQueue *prevNode = NULL;
    stMessageQueue *tmpNode = NULL;

    tmpNode = _messageQueue;
    if(tmpNode == NULL)
    {
        return;
    }
    while(tmpNode != NULL)
    {
        prevNode = tmpNode;
        tmpNode = tmpNode->next;
        free(prevNode);
        prevNode = NULL;
    }
    _messageQueue = NULL;
}

/************************************************************
*功能：获取消息队列中空的节点，加锁操作
*输入：无
*输出：无
*返回：true成功
*/
bool GtMessageQueue::getEmptyNodeSecure(int *offset, stMessageItem *item)
{
    bool result = false;

    if(!lock())
    {
        return false;
    }
    result = getEmptyNode(offset, item);
    if(!unlock())
    {
        return false;
    }
    return result;
}

/************************************************************
*功能：获取消息队列中空的节点
*输入：无
*输出：无
*返回：true成功
*/
bool GtMessageQueue::getEmptyNode(int *offset, stMessageItem *item)
{
    int index = 0;
    stMessageQueue *node = NULL;

    node = _messageQueue;
    if(node == NULL)
    {
        return false;
    }
    while(node != NULL)
    {
        if(node->item.unStatus == 0)
        {
            memcpy(&(node->item), item, sizeof(stMessageItem));
            *offset = index;
            return true;
        }
        else
        {
            node = node->next;
            index++;
        }
    }
    return false;
}

/************************************************************
*功能：获取指定位置的消息队列节点，加锁操作
*输入：index消息队列索引
*输出：item消息队列节点属性
*返回：true成功
*/
bool GtMessageQueue::getNodeSecure(int index, stMessageItem *item)
{
    bool result = false;

    if(!lock())
    {
        return false;
    }
    result = getNode(index, item);
    if(!unlock())
    {
        return false;
    }
    return result;
}

/************************************************************
*功能：获取指定位置的消息队列节点
*输入：index消息队列索引
*输出：item消息队列节点属性
*返回：true成功
*/
bool GtMessageQueue::getNode(int index, stMessageItem *item)
{
    int sn = 0;
    stMessageQueue *node = NULL;

    if(item == NULL || index < 0)
    {
        return false;
    }
    node = _messageQueue;
    while(node != NULL)
    {
        if(index == sn)
        {
            memcpy(item, &node->item, sizeof(stMessageItem));
            return true;
        }
        else
        {
            node = node->next;
            sn++;
        }
    }
    return false;
}

/************************************************************
*功能：刷新指定位置的消息队列节点，加锁操作
*输入：index消息队列索引
*输入：item消息队列节点属性
*输出：无
*返回：true成功
*/
bool GtMessageQueue::setNodeSecure(int index, stMessageItem *item)
{
    bool result = false;

    if(!lock())
    {
        return false;
    }
    result = setNode(index, item);
    if(!unlock())
    {
        return false;
    }
    return result;
}

/************************************************************
*功能：刷新指定位置的消息队列节点
*输入：index消息队列索引
*输入：item消息队列节点属性
*输出：无
*返回：true成功
*/
bool GtMessageQueue::setNode(int index, stMessageItem *item)
{
    int sn = 0;
    stMessageQueue *node = NULL;

    if(index < 0 || item == NULL)
    {
        return false;
    }
    node = _messageQueue;
    while(node != NULL)
    {
        if(index == sn)
        {
            memcpy(&node->item, item, sizeof(stMessageItem));
            return true;
        }
        else
        {
            node = node->next;
            sn++;
        }
    }
    return false;
}

/************************************************************
*功能：将指定位置的消息节点移动到消息队列末尾，并清除其属性数据，加锁操作
*输入：index消息队列索引
*输出：无
*返回：!=0错误
*/
bool GtMessageQueue::recycleNodeSecure(int index)
{
    bool result = false;

    if(!lock())
    {
        return false;
    }
    result = recycleNode(index);
    if(!unlock())
    {
        return false;
    }
    return result;
}

/************************************************************
*功能：将指定位置的消息节点移动到消息队列末尾，并清除其属性数据
*输入：index消息队列索引
*输出：无
*返回：!=0错误
*/
bool GtMessageQueue::recycleNode(int index)
{
    int sn = 0;
    stMessageQueue *node = NULL;
    stMessageQueue *prevNode = NULL;
    stMessageQueue *endNode = NULL;

    if(index < 0)
    {
        return false;
    }
    node = _messageQueue;
    if(node != NULL && node->next == NULL)
    {
        memset(&node->item, 0, sizeof(stMessageItem));
        return true;
    }
    while(node != NULL)
    {
        if(index == sn)
        {
            if(sn == 0)
            {
                _messageQueue = _messageQueue->next;
            }
            else
            {
                prevNode->next = node->next;
            }
            endNode = _messageQueue;
            while(endNode->next != NULL)
            {
                endNode = endNode->next;
            }
            endNode->next = node;
            node->next = NULL;
            memset(&node->item, 0, sizeof(stMessageItem));
            return true;
        }
        else
        {
            prevNode = node;
            node = node->next;
            sn++;
        }
    }
    return false;
}

/************************************************************
*功能：加锁
*输入：无
*输出：无
*返回：true,false
*/
bool GtMessageQueue::lock()
{
    if(pthread_mutex_lock(&_mutex) != 0)
    {
        return false;
    }
    return true;
}

/************************************************************
*功能：解锁
*输入：无
*输出：无
*返回：true,false
*/
bool GtMessageQueue::unlock()
{
    if(pthread_mutex_unlock(&_mutex) != 0)
    {
        return false;
    }
    return true;
}