/*
 *
 *  D-Bus++ - C++ bindings for D-Bus
 *
 *  Copyright (C) 2005-2007  Paolo Durante <shackan@gmail.com>
 *
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <cassert>

#include <dbus-c++/dispatcher.h>

#include <dbus/dbus.h>

#include "dispatcher_p.h"
#include "server_p.h"
#include "connection_p.h"

DBus::Dispatcher *DBus::default_dispatcher = NULL;

using namespace DBus;

Timeout::Timeout(Timeout::Internal *i)
: _int(i)
{
	dbus_timeout_set_data((DBusTimeout *)i, this, NULL);
}

int Timeout::interval() const
{
	return dbus_timeout_get_interval((DBusTimeout *)_int);
}

bool Timeout::enabled() const
{
	return dbus_timeout_get_enabled((DBusTimeout *)_int);
}

bool Timeout::handle()
{
	return dbus_timeout_handle((DBusTimeout *)_int);
}

/*
*/

Watch::Watch(Watch::Internal *i)
: _int(i)
{
	dbus_watch_set_data((DBusWatch *)i, this, NULL);
}

int Watch::descriptor() const
{
#if HAVE_WIN32
	return dbus_watch_get_socket((DBusWatch*)_int);
#else
	return dbus_watch_get_unix_fd((DBusWatch*)_int);
#endif
}

int Watch::flags() const
{
	return dbus_watch_get_flags((DBusWatch *)_int);
}

bool Watch::enabled() const
{
	return dbus_watch_get_enabled((DBusWatch *)_int);
}

bool Watch::handle(int flags)
{
	return dbus_watch_handle((DBusWatch *)_int, flags);
}

/*
*/

dbus_bool_t Dispatcher::Private::on_add_watch(DBusWatch *watch, void *data)
{
	Dispatcher *d = static_cast<Dispatcher *>(data);

	Watch::Internal *w = reinterpret_cast<Watch::Internal *>(watch);

	d->add_watch(w);

	return true;
}

void Dispatcher::Private::on_rem_watch(DBusWatch *watch, void *data)
{
	Dispatcher *d = static_cast<Dispatcher *>(data);

	Watch *w = static_cast<Watch *>(dbus_watch_get_data(watch));

	d->rem_watch(w);
}

void Dispatcher::Private::on_toggle_watch(DBusWatch *watch, void *data)
{
	Watch *w = static_cast<Watch *>(dbus_watch_get_data(watch));

	w->toggle();
}

dbus_bool_t Dispatcher::Private::on_add_timeout(DBusTimeout *timeout, void *data)
{
	Dispatcher *d = static_cast<Dispatcher *>(data);

	Timeout::Internal *t = reinterpret_cast<Timeout::Internal *>(timeout);

	d->add_timeout(t);

	return true;
}

void Dispatcher::Private::on_rem_timeout(DBusTimeout *timeout, void *data)
{
	Dispatcher *d = static_cast<Dispatcher *>(data);

	Timeout *t = static_cast<Timeout *>(dbus_timeout_get_data(timeout));

	d->rem_timeout(t);
}

void Dispatcher::Private::on_toggle_timeout(DBusTimeout *timeout, void *data)
{
	Timeout *t = static_cast<Timeout *>(dbus_timeout_get_data(timeout));

	t->toggle();
}

void Dispatcher::queue_connection(Connection::Private *cp)
{
	_mutex_p.lock();
	_pending_queue.push_back(cp);
	_mutex_p.unlock();
}


bool Dispatcher::has_something_to_dispatch()
{
	_mutex_p.lock();
	bool has_something = false;
	for(Connection::PrivatePList::iterator it = _pending_queue.begin();
		it != _pending_queue.end() && !has_something;
		++it)
	{
		has_something = (*it)->has_something_to_dispatch();
	}

	_mutex_p.unlock();
	return has_something;
}


void Dispatcher::dispatch_pending()
{
	_mutex_p.lock();

	// Reentrancy is not permitted for this function
	assert(!_dispatching);
	_dispatching = true;

	// SEEME: dbus-glib is dispatching only one message at a time to not starve the loop/other things...

	while (_pending_queue.size() > 0)
	{
		Connection::PrivatePList::iterator i, j;
		i = _pending_queue.begin();
		while (i != _pending_queue.end())
		{
			j = i;
			++j;
			_mutex_p.unlock();
			bool done = (*i)->do_dispatch();
			_mutex_p.lock();
			if (done)
				_pending_queue.erase(i);

			i = j;
		}
	}
	_dispatching = false;
	_mutex_p.unlock();
}

void DBus::_init_threading()
{
#ifdef DBUS_HAS_THREADS_INIT_DEFAULT
	dbus_threads_init_default();
#else
	debug_log("Thread support is not enabled! Your D-Bus version is too old!");
#endif//DBUS_HAS_THREADS_INIT_DEFAULT
}

void DBus::_init_threading(
	MutexNewFn m1,
	MutexFreeFn m2,
	MutexLockFn m3,
	MutexUnlockFn m4,
	CondVarNewFn c1,
	CondVarFreeFn c2,
	CondVarWaitFn c3,
	CondVarWaitTimeoutFn c4,
	CondVarWakeOneFn c5,
	CondVarWakeAllFn c6
)
{
#ifndef DBUS_HAS_RECURSIVE_MUTEX
	DBusThreadFunctions functions = {
		DBUS_THREAD_FUNCTIONS_MUTEX_NEW_MASK |
		DBUS_THREAD_FUNCTIONS_MUTEX_FREE_MASK |
		DBUS_THREAD_FUNCTIONS_MUTEX_LOCK_MASK |
		DBUS_THREAD_FUNCTIONS_MUTEX_UNLOCK_MASK |
		DBUS_THREAD_FUNCTIONS_CONDVAR_NEW_MASK |
		DBUS_THREAD_FUNCTIONS_CONDVAR_FREE_MASK |
		DBUS_THREAD_FUNCTIONS_CONDVAR_WAIT_MASK |
		DBUS_THREAD_FUNCTIONS_CONDVAR_WAIT_TIMEOUT_MASK |
		DBUS_THREAD_FUNCTIONS_CONDVAR_WAKE_ONE_MASK|
		DBUS_THREAD_FUNCTIONS_CONDVAR_WAKE_ALL_MASK,
		(DBusMutexNewFunction) m1,
		(DBusMutexFreeFunction) m2,
		(DBusMutexLockFunction) m3,
		(DBusMutexUnlockFunction) m4,
		(DBusCondVarNewFunction) c1,
		(DBusCondVarFreeFunction) c2,
		(DBusCondVarWaitFunction) c3,
		(DBusCondVarWaitTimeoutFunction) c4,
		(DBusCondVarWakeOneFunction) c5,
		(DBusCondVarWakeAllFunction) c6
	};
#else
	DBusThreadFunctions functions = {
		DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_NEW_MASK |
		DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_FREE_MASK |
		DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_LOCK_MASK |
		DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_UNLOCK_MASK |
		DBUS_THREAD_FUNCTIONS_CONDVAR_NEW_MASK |
		DBUS_THREAD_FUNCTIONS_CONDVAR_FREE_MASK |
		DBUS_THREAD_FUNCTIONS_CONDVAR_WAIT_MASK |
		DBUS_THREAD_FUNCTIONS_CONDVAR_WAIT_TIMEOUT_MASK |
		DBUS_THREAD_FUNCTIONS_CONDVAR_WAKE_ONE_MASK|
		DBUS_THREAD_FUNCTIONS_CONDVAR_WAKE_ALL_MASK,
		0, 0, 0, 0,
		(DBusCondVarNewFunction) c1,
		(DBusCondVarFreeFunction) c2,
		(DBusCondVarWaitFunction) c3,
		(DBusCondVarWaitTimeoutFunction) c4,
		(DBusCondVarWakeOneFunction) c5,
		(DBusCondVarWakeAllFunction) c6,
		(DBusRecursiveMutexNewFunction) m1,
		(DBusRecursiveMutexFreeFunction) m2,
		(DBusRecursiveMutexLockFunction) m3,
		(DBusRecursiveMutexUnlockFunction) m4
	};
#endif//DBUS_HAS_RECURSIVE_MUTEX
	dbus_threads_init(&functions);
}
