/*
 *
 *  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 <dbus-c++/debug.h>
#include <dbus-c++/connection.h>

#include <dbus/dbus.h>
#include <string>

#include "internalerror.h"

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

using namespace DBus;

Connection::Private::Private(DBusConnection *c, Server::Private *s)
: conn(c) , dispatcher(0), server(s)
{
	init();
}

Connection::Private::Private(DBusBusType type)
{
	InternalError e;

	conn = dbus_bus_get_private(type, e);

	if (e) throw Error(e);

	init();
}

Connection::Private::~Private()
{
	debug_log("terminating connection 0x%08x", conn);

	detach_server();

	if (dbus_connection_get_is_connected(conn))
	{
		std::vector<std::string>::iterator i = names.begin();

		while (i != names.end())
		{
			debug_log("%s: releasing bus name %s", dbus_bus_get_unique_name(conn), i->c_str());
			dbus_bus_release_name(conn, i->c_str(), NULL);
			++i;
		}
		dbus_connection_close(conn);
	}
	dbus_connection_unref(conn);
}

void Connection::Private::init()
{
	dbus_connection_ref(conn);
	dbus_connection_ref(conn);	//todo: the library has to own another reference

	disconn_filter = new Callback<Connection::Private, bool, const Message &>(
		this, &Connection::Private::disconn_filter_function
	);

	dbus_connection_add_filter(conn, message_filter_stub, &disconn_filter, NULL); // TODO: some assert at least

	dbus_connection_set_dispatch_status_function(conn, dispatch_status_stub, this, 0);
	dbus_connection_set_exit_on_disconnect(conn, false); //why was this set to true??
}

void Connection::Private::detach_server()
{
/*	Server::Private *tmp = server;

	server = NULL;

	if (tmp)
	{
		ConnectionList::iterator i;

		for (i = tmp->connections.begin(); i != tmp->connections.end(); ++i)
		{
			if (i->_pvt.get() == this)
			{
				tmp->connections.erase(i);
				break;
			}
		}
	}*/
}

bool Connection::Private::do_dispatch()
{
	debug_log("dispatching on %p", conn);

	if (!dbus_connection_get_is_connected(conn))
	{
		debug_log("connection terminated");

		detach_server();

		return true;
	}

	return dbus_connection_dispatch(conn) != DBUS_DISPATCH_DATA_REMAINS;
}

void Connection::Private::dispatch_status_stub(DBusConnection *dc, DBusDispatchStatus status, void *data)
{
	Private *p = static_cast<Private *>(data);

	switch (status)
	{
		case DBUS_DISPATCH_DATA_REMAINS:
		debug_log("some dispatching to do on %p", dc);
		p->dispatcher->queue_connection(p);
		break;

		case DBUS_DISPATCH_COMPLETE:
		debug_log("all dispatching done on %p", dc);
		break;

		case DBUS_DISPATCH_NEED_MEMORY: //uh oh...
		debug_log("connection %p needs memory", dc);
		break;
	}
}

DBusHandlerResult Connection::Private::message_filter_stub(DBusConnection *conn, DBusMessage *dmsg, void *data)
{
	MessageSlot *slot = static_cast<MessageSlot *>(data);

	Message msg = Message(new Message::Private(dmsg));

	return slot && !slot->empty() && slot->call(msg) 
			? DBUS_HANDLER_RESULT_HANDLED
			: DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}

bool Connection::Private::disconn_filter_function(const Message &msg)
{
	if (msg.is_signal(DBUS_INTERFACE_LOCAL,"Disconnected"))
	{
		debug_log("%p disconnected by local bus", conn);
		dbus_connection_close(conn);

		return true;
	}
	return false;
}

DBusDispatchStatus Connection::Private::dispatch_status()
{
	return dbus_connection_get_dispatch_status(conn);
}

bool Connection::Private::has_something_to_dispatch()
{
	return dispatch_status() == DBUS_DISPATCH_DATA_REMAINS;
}


Connection Connection::SystemBus()
{
	return Connection(new Private(DBUS_BUS_SYSTEM));
}

Connection Connection::SessionBus()
{
	return Connection(new Private(DBUS_BUS_SESSION));
}

Connection Connection::ActivationBus()
{
	return Connection(new Private(DBUS_BUS_STARTER));
}

Connection::Connection(const char *address, bool priv)
: _timeout(-1)
{
	InternalError e;
	DBusConnection *conn = priv 
		? dbus_connection_open_private(address, e)
		: dbus_connection_open(address, e);

	if (e) throw Error(e);

	_pvt = new Private(conn);

	setup(default_dispatcher);

	debug_log("connected to %s", address);
}

Connection::Connection(Connection::Private *p)
: _pvt(p), _timeout(-1)
{
	setup(default_dispatcher);
}

Connection::Connection(const Connection &c)
: _pvt(c._pvt),_timeout(c._timeout)
{
	dbus_connection_ref(_pvt->conn);
}

Connection::~Connection()
{
	dbus_connection_unref(_pvt->conn);
}

Dispatcher *Connection::setup(Dispatcher *dispatcher)
{
	debug_log("registering stubs for connection %p", _pvt->conn);

	if (!dispatcher) dispatcher = default_dispatcher;

	if (!dispatcher) throw ErrorFailed("no default dispatcher set for new connection");

	Dispatcher *prev = _pvt->dispatcher;

	_pvt->dispatcher = dispatcher;

	dispatcher->queue_connection(_pvt.get());

	dbus_connection_set_watch_functions(
		_pvt->conn,
		Dispatcher::Private::on_add_watch,
		Dispatcher::Private::on_rem_watch,
		Dispatcher::Private::on_toggle_watch,
		dispatcher,
		0
	);

	dbus_connection_set_timeout_functions(
		_pvt->conn,
		Dispatcher::Private::on_add_timeout,
		Dispatcher::Private::on_rem_timeout,
		Dispatcher::Private::on_toggle_timeout,
		dispatcher,
		0
	);

	return prev;
}

bool Connection::operator == (const Connection &c) const
{
	return _pvt->conn == c._pvt->conn;
}

bool Connection::register_bus()
{
	InternalError e;

	bool r = dbus_bus_register(_pvt->conn, e);
  
	if (e) throw (e);

	return r;
}

bool Connection::connected() const
{
	return dbus_connection_get_is_connected(_pvt->conn);
}

void Connection::disconnect()
{
//	dbus_connection_disconnect(_pvt->conn); // disappeared in 0.9x
	dbus_connection_close(_pvt->conn);
}

void Connection::exit_on_disconnect(bool exit)
{
	dbus_connection_set_exit_on_disconnect(_pvt->conn, exit);
}

bool Connection::unique_name(const char *n)
{
	return dbus_bus_set_unique_name(_pvt->conn, n);
}

const char *Connection::unique_name() const
{
	return dbus_bus_get_unique_name(_pvt->conn);
}

void Connection::flush()
{
	dbus_connection_flush(_pvt->conn);
}

void Connection::add_match(const char *rule)
{
	InternalError e;

	dbus_bus_add_match(_pvt->conn, rule, e);

	debug_log("%s: added match rule %s", unique_name(), rule);

	if (e) throw Error(e);
}

void Connection::remove_match(const char *rule)
{
	InternalError e;
	
	dbus_bus_remove_match(_pvt->conn, rule, e);

	debug_log("%s: removed match rule %s", unique_name(), rule);

	if (e) throw Error(e);
}

bool Connection::add_filter(MessageSlot &s)
{
	debug_log("%s: adding filter", unique_name());
	return dbus_connection_add_filter(_pvt->conn, Private::message_filter_stub, &s, NULL);
}

void Connection::remove_filter(MessageSlot &s)
{
	debug_log("%s: removing filter", unique_name());
	dbus_connection_remove_filter(_pvt->conn, Private::message_filter_stub, &s);
}

bool Connection::send(const Message &msg, unsigned int *serial)
{
	return dbus_connection_send(_pvt->conn, msg._pvt->msg, serial);
}

Message Connection::send_blocking(Message &msg, int timeout)
{
	DBusMessage *reply;
	InternalError e;
	
	if (this->_timeout != -1)
	{
		reply = dbus_connection_send_with_reply_and_block(_pvt->conn, msg._pvt->msg, this->_timeout, e);
	}
	else
	{
		reply = dbus_connection_send_with_reply_and_block(_pvt->conn, msg._pvt->msg, timeout, e);
	}

	if (e) throw Error(e);

	return Message(new Message::Private(reply), false);
}

PendingCall *Connection::send_async(Message &msg, int timeout)
{
	DBusPendingCall *pending;

	// TODO(ers) At the moment using a timeout other than -1
	// results in a deadlock if the timeout expires.
	if (!dbus_connection_send_with_reply(_pvt->conn, msg._pvt->msg, &pending, timeout))
	{
		throw ErrorNoMemory("Unable to start asynchronous call");
	}
	return new PendingCall(new PendingCall::Private(pending));
}

int Connection::_request_name(const char *name, int flags)
{
	InternalError e;

	debug_log("%s: registering bus name %s", unique_name(), name);

	int ret = dbus_bus_request_name(_pvt->conn, name, flags, e);

	if (ret == -1)
	{
		if (e) throw Error(e);
	}

//	this->remove_match("destination");

	if (name)
	{
		_pvt->names.push_back(name);
		std::string match = "destination='" + _pvt->names.back() + "'";
		add_match(match.c_str());
	}

	return ret;
}

void Connection::request_name(const char *name, int flags)
{
	/*
	 * TODO:
	 * Think about giving back the 'ret' value. Some people on the list
	 * requested about this...
	 */
	_request_name(name, flags);
}

bool Connection::acquire_name(const char *name)
{
	/*
	 * Request the desired name, allowing the request to be queued.
	 */
	int ret = _request_name(name, 0);
	switch (ret) {
		case DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER:
		case DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER:
			return true;
		case DBUS_REQUEST_NAME_REPLY_IN_QUEUE:
			break;
		case DBUS_REQUEST_NAME_REPLY_EXISTS:
		default:
			// Unexpected, but try to keep going.
			debug_log("%s: unexpected reply %d for RequestName",
				  dbus_bus_get_unique_name(_pvt->conn), ret);
			break;
	}

	/*
	 * We didn't get the name. Perhaps the name owner terminated
	 * abruptly, and dbus-daemon doesn't know that yet.  Ask
	 * dbus-daemon to check if the name owner is still up.
	 */
	CallMessage ping_request(name, "/", "org.freedesktop.DBus.Peer", "Ping");
	try {
		send_blocking(ping_request, DBUS_TIMEOUT_USE_DEFAULT);
	} catch (const DBus::Error &) {
		/*
		 * We don't care if the ping request times out or generates
                 * some other error. We only care about its side-effect.
		 */
	}

	/*
	 * Now that we've nudged dbus-daemon, try requesting the name
	 * one more time. Note that we may already be the owner at
	 * this point, because our first attempt allowed queuing the
	 * request.
	 */
	ret = _request_name(name, DBUS_NAME_FLAG_DO_NOT_QUEUE);
	switch (ret) {
		case DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER:
		case DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER:
			return true;
		case DBUS_REQUEST_NAME_REPLY_EXISTS:
			return false;
		case DBUS_REQUEST_NAME_REPLY_IN_QUEUE:
		default:
			// Log unexpected response.
			debug_log("%s: unexpected reply %d for RequestName",
				  dbus_bus_get_unique_name(_pvt->conn), ret);
			return false;
	}
}

unsigned long Connection::sender_unix_uid(const char *sender)
{
    InternalError e;
    
    unsigned long ul = dbus_bus_get_unix_user(_pvt->conn, sender, e);
    
    if (e) throw Error(e);
    
    return ul;
}

bool Connection::has_name(const char *name)
{	
	InternalError e;

	bool b = dbus_bus_name_has_owner(_pvt->conn, name, e);

	if (e) throw Error(e);

	return b;
}

const std::vector<std::string>& Connection::names()
{
	return _pvt->names;
}

bool Connection::start_service(const char *name, unsigned long flags)
{
	InternalError e;

	bool b = dbus_bus_start_service_by_name(_pvt->conn, name, flags, NULL, e);

	if (e) throw Error(e);
	
	return b;
}

void Connection::set_timeout(int timeout)
{
	_timeout=timeout;
}
	
int Connection::get_timeout()
{
	return _timeout;
}
