/*
 * QrfeMessageQueue.cpp
 *
 *  Created on: 22.06.2010
 *      Author: stefan.detter
 */

#include "QrfeMessageQueue.h"

#include <QMutexLocker>
#include <QTime>

#include <QrfeSleeper>

QrfeMessageQueue::QrfeMessageQueue(QObject* parent)
	: QObject(parent)
	, QrfeTraceModule("QrfeMessageQueue")
{
	m_singleThread = false;
	m_messageMutex = new QMutex(QMutex::Recursive);
}

QrfeMessageQueue::~QrfeMessageQueue()
{
	delete m_messageMutex;
}

void QrfeMessageQueue::setSingleThread(bool alive)
{
	m_singleThread = alive;
}

bool QrfeMessageQueue::currentlyWaiting()
{
	if(m_messageMutex->tryLock(1)){
		m_messageMutex->unlock();
		return false;
	}
	else
		return true;
}


void QrfeMessageQueue::clearMessage (int id)
{
	m_messageMutex->lock();
	m_messages.remove(id);
	m_messageMutex->unlock();
}

QByteArray QrfeMessageQueue::waitForMessage (int id, uint msecs, bool *ok)
{
	QByteArray ret;

	if(m_singleThread)
	{
		uint i = 0;
		uint cycles = msecs/10;

		*ok = false;

		// check for the flag for the given time
		while(i++ < cycles)
		{
			if(m_messages.contains(id) && m_messages.value(id).size() > 0)
				break;
			QrfeSleeper::MSleepAlive(10);
		}

		if(m_messages.contains(id) && m_messages.value(id).size() > 0)
		{
			*ok = true;

			m_messageMutex->lock();
			ret = m_messages[id].takeFirst();
			if(m_messages.value(id).size() == 0)
				m_messages.remove(id);
			m_messageMutex->unlock();
		}

		return ret;
	}
	else
	{
		*ok = false;

		QTime t;
		t.start();
		while(1)
		{
			uint elapsed = t.elapsed();
			if(elapsed > msecs){
				return ret;
			}

			QMutexLocker lock(&m_waitMutex);
	        if(!m_messages.contains(id))
	        {
	        	*ok = m_messageAvailable.wait(&m_waitMutex, msecs - elapsed);
	        }

			if(m_messages.contains(id) && m_messages.value(id).size() > 0)
			{
				m_messageMutex->lock();
				ret = m_messages[id].takeFirst();
				if(m_messages.value(id).size() == 0)
					m_messages.remove(id);
				m_messageMutex->unlock();
				*ok = true;
				return ret;
			}
		}
	}

	return ret;
}

void QrfeMessageQueue::enqueMessage (int id, const QByteArray& message)
{
	QMutexLocker lock(&m_waitMutex);
	m_messageMutex->lock();
	m_messages[id].append(message);
	m_messageMutex->unlock();
	m_messageAvailable.wakeAll();
}


/*
void QrfeMessageQueue::queuePacket ( const iAPPacket&  packet, ushort transId) {
  QMutexLocker lock(&m_mutex);
  if(m_useTransId) {
    m_transIdQueue.insertMulti(transId, packet);
    m_mutexCondition.wakeAll();
  }
  else {
    m_nontransIdQueue.insertMulti(packet.uid(), packet);
    m_mutexCondition.wakeAll();
  }
}

void QrfeMessageQueue::waitForPacket(ulong timeout) {
  QMutexLocker lock(&m_mutex);
  m_mutexCondition.wait(&m_mutex, timeout);
}
*/
