/*
 *
 *  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++/message.h>

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

#include "internalerror.h"
#include "message_p.h"

using namespace DBus;

/*
*/

MessageIter::MessageIter()
: _pvt(new Private), _msg(NULL) {}

MessageIter::MessageIter(Message &msg)
: _pvt(new Private), _msg(&msg) {}

MessageIter::MessageIter(const MessageIter &iter)
: _pvt(new Private(*iter._pvt)), _msg(iter._msg) {}

MessageIter::~MessageIter()
{
	delete _pvt;
	_pvt = NULL;
	_msg = NULL;
}

MessageIter &MessageIter::operator =(const MessageIter &iter)
{
	if (this != &iter)
	{
		*_pvt = *iter._pvt;
		_msg = iter._msg;
	}
	return *this;
}

int MessageIter::type()
{
	return dbus_message_iter_get_arg_type(&_pvt->iter);
}

bool MessageIter::at_end()
{
	return type() == DBUS_TYPE_INVALID;
}

bool MessageIter::has_next()
{
	return dbus_message_iter_has_next(&_pvt->iter);
}

MessageIter &MessageIter::operator ++()
{
	dbus_message_iter_next(&_pvt->iter);
	return (*this);
}

MessageIter MessageIter::operator ++(int)
{
	MessageIter copy(*this);
	++(*this);
	return copy;
}

bool MessageIter::append_basic(int type_id, void *value)
{
	return dbus_message_iter_append_basic(&_pvt->iter, type_id, value);
}

void MessageIter::get_basic(int type_id, void *ptr)
{
	if (type() != type_id)
		throw ErrorInvalidArgs("type mismatch");

	dbus_message_iter_get_basic(&_pvt->iter, ptr);
}

bool MessageIter::append_byte(unsigned char b)
{
	return append_basic(DBUS_TYPE_BYTE, &b);
}

unsigned char MessageIter::get_byte()
{
 	unsigned char b;
	get_basic(DBUS_TYPE_BYTE, &b);
 	return b;
}

bool MessageIter::append_bool(bool b)
{
	dbus_bool_t db = b ? TRUE : FALSE;
	return append_basic(DBUS_TYPE_BOOLEAN, &db);
}

bool MessageIter::get_bool()
{
 	dbus_bool_t db;
	get_basic(DBUS_TYPE_BOOLEAN, &db);
	return db ? true : false;
}

bool MessageIter::append_int16(signed short i)
{
	return append_basic(DBUS_TYPE_INT16, &i);
}

signed short MessageIter::get_int16()
{
 	signed short i;
	get_basic(DBUS_TYPE_INT16, &i);
 	return i;
}

bool MessageIter::append_uint16(unsigned short u)
{
	return append_basic(DBUS_TYPE_UINT16, &u);
}

unsigned short MessageIter::get_uint16()
{
	unsigned short u;
	get_basic(DBUS_TYPE_UINT16, &u);
 	return u;
}

bool MessageIter::append_int32(signed int i)
{
	return append_basic(DBUS_TYPE_INT32, &i);
}

signed int MessageIter::get_int32()
{
 	signed int i;
	get_basic(DBUS_TYPE_INT32, &i);
 	return i;
}

bool MessageIter::append_uint32(unsigned int u)
{
	return append_basic(DBUS_TYPE_UINT32, &u);
}

unsigned int MessageIter::get_uint32()
{
	unsigned int u;
	get_basic(DBUS_TYPE_UINT32, &u);
 	return u;
}

signed long long MessageIter::get_int64()
{
	signed long long i;
	get_basic(DBUS_TYPE_INT64, &i);
	return i;
}

bool MessageIter::append_int64(signed long long i)
{
	return append_basic(DBUS_TYPE_INT64, &i);
}

unsigned long long MessageIter::get_uint64()
{
	unsigned long long u;
	get_basic(DBUS_TYPE_UINT64, &u);
	return u;
}

bool MessageIter::append_uint64(unsigned long long u)
{
	return append_basic(DBUS_TYPE_UINT64, &u);
}

double MessageIter::get_double()
{
	double d;
	get_basic(DBUS_TYPE_DOUBLE, &d);
	return d;
}

bool MessageIter::append_double(double d)
{
	return append_basic(DBUS_TYPE_DOUBLE, &d);
}

bool MessageIter::append_string(const char *chars)
{
	return append_basic(DBUS_TYPE_STRING, &chars);
}

const char *MessageIter::get_string()
{
	char *chars;
	get_basic(DBUS_TYPE_STRING, &chars);
 	return chars;
}

bool MessageIter::append_path(const char *chars)
{
	return append_basic(DBUS_TYPE_OBJECT_PATH, &chars);
}

const char *MessageIter::get_path()
{
	char *chars;
	get_basic(DBUS_TYPE_OBJECT_PATH, &chars);
 	return chars;
}

bool MessageIter::append_signature(const char *chars)
{
	return append_basic(DBUS_TYPE_SIGNATURE, &chars);
}

const char *MessageIter::get_signature()
{
	char *chars;
	get_basic(DBUS_TYPE_SIGNATURE, &chars);
 	return chars;
}

bool MessageIter::append_fd(int fd)
{
	return append_basic(DBUS_TYPE_UNIX_FD, &fd);
}

int MessageIter::get_fd()
{
	int fd;
	get_basic(DBUS_TYPE_UNIX_FD, &fd);
	return fd;
}

MessageIter MessageIter::recurse()
{
	MessageIter iter(msg());
	dbus_message_iter_recurse(&_pvt->iter, &iter._pvt->iter);
	return iter;
}

char *MessageIter::signature() const
{
	return dbus_message_iter_get_signature(&_pvt->iter);
}

bool MessageIter::append_array(char type, const void *ptr, size_t length)
{
	return dbus_message_iter_append_fixed_array(&_pvt->iter, type, &ptr, length);
}

int MessageIter::array_type()
{
	return dbus_message_iter_get_element_type(&_pvt->iter);
}

int MessageIter::get_array(void *ptr)
{
	int length;
	dbus_message_iter_get_fixed_array(&_pvt->iter, ptr, &length);
	return length;
}

bool MessageIter::is_array()
{
	return dbus_message_iter_get_arg_type(&_pvt->iter) == DBUS_TYPE_ARRAY;
}

bool MessageIter::is_dict()
{
	return is_array() && dbus_message_iter_get_element_type(&_pvt->iter) == DBUS_TYPE_DICT_ENTRY;
}

MessageIter MessageIter::new_array(const char *sig)
{
	MessageIter arr(msg());
	dbus_message_iter_open_container(
		&_pvt->iter, DBUS_TYPE_ARRAY, sig, &arr._pvt->iter
	);
	return arr;
}

MessageIter MessageIter::new_variant(const char *sig)
{
	MessageIter var(msg());
	dbus_message_iter_open_container(
		&_pvt->iter, DBUS_TYPE_VARIANT, sig, &var._pvt->iter
	);
	return var;
}

MessageIter MessageIter::new_struct()
{
	MessageIter stu(msg());
	dbus_message_iter_open_container(
		&_pvt->iter, DBUS_TYPE_STRUCT, NULL, &stu._pvt->iter
	);
	return stu;
}

MessageIter MessageIter::new_dict_entry()
{
	MessageIter ent(msg());
	dbus_message_iter_open_container(
		&_pvt->iter, DBUS_TYPE_DICT_ENTRY, NULL, &ent._pvt->iter
	);
	return ent;
}

void MessageIter::close_container(MessageIter &container)
{
	dbus_message_iter_close_container(&_pvt->iter, &container._pvt->iter);
}

static bool is_basic_type(int typecode)
{
	switch (typecode)
	{
		case DBUS_TYPE_BYTE:
		case DBUS_TYPE_BOOLEAN:
		case DBUS_TYPE_INT16:
		case DBUS_TYPE_UINT16:
		case DBUS_TYPE_INT32:
		case DBUS_TYPE_UINT32:
		case DBUS_TYPE_INT64:
		case DBUS_TYPE_UINT64:
		case DBUS_TYPE_DOUBLE:
		case DBUS_TYPE_STRING:
		case DBUS_TYPE_OBJECT_PATH:
		case DBUS_TYPE_SIGNATURE:
		case DBUS_TYPE_UNIX_FD:
			return true;
		default:
			return false;
	}
}

void MessageIter::copy_data(MessageIter &to)
{
	for (MessageIter &from = *this; !from.at_end(); ++from)
	{
		if (is_basic_type(from.type()))
		{
			debug_log("copying basic type: %c", from.type());

			unsigned char value[8];
			from.get_basic(from.type(), &value);
			to.append_basic(from.type(), &value);
		}
		else
		{
			MessageIter from_container = from.recurse();
			char *sig = from_container.signature();

			debug_log("copying compound type: %c[%s]", from.type(), sig);

			MessageIter to_container (to.msg());
			dbus_message_iter_open_container
			(
				&to._pvt->iter,
				from.type(),
				from.type() == DBUS_TYPE_DICT_ENTRY ||
				from.type() == DBUS_TYPE_STRUCT ? NULL : sig,
				&to_container._pvt->iter
			);

			from_container.copy_data(to_container);
			to.close_container(to_container);
			free(sig);
		}
	}
}

/*
*/

Message::Message()
: _pvt(new Private)
{
}

Message::Message(Message::Private *p, bool incref)
: _pvt(p)
{
	if (_pvt->msg && incref) dbus_message_ref(_pvt->msg);
}

Message::Message(const Message &m)
: _pvt(m._pvt)
{
	if (_pvt->msg)
		dbus_message_ref(_pvt->msg);
}

Message::~Message()
{
	if (_pvt->msg)
		dbus_message_unref(_pvt->msg);
}

Message &Message::operator = (const Message &m)
{
	if (&m != this)
	{
		if (_pvt->msg)
			dbus_message_unref(_pvt->msg);
		_pvt = m._pvt;
		if (_pvt->msg)
			dbus_message_ref(_pvt->msg);
	}
	return *this;
}

Message Message::copy()
{
	Private *pvt = new Private(_pvt->msg ? dbus_message_copy(_pvt->msg) : NULL);
	return Message(pvt);
}

bool Message::append(int first_type, ...)
{
	va_list vl;
	va_start(vl, first_type);

	bool b = dbus_message_append_args_valist(_pvt->msg, first_type, vl);

	va_end(vl);
	return b;
}

void Message::terminate()
{
	dbus_message_append_args(_pvt->msg, DBUS_TYPE_INVALID);
}

int Message::type() const
{
	return dbus_message_get_type(_pvt->msg);
}

int Message::serial() const
{
	return dbus_message_get_serial(_pvt->msg);
}

int Message::reply_serial() const
{
	return dbus_message_get_reply_serial(_pvt->msg);
}

bool Message::reply_serial(int s)
{
	return dbus_message_set_reply_serial(_pvt->msg, s);
}

const char *Message::sender() const
{
	return dbus_message_get_sender(_pvt->msg);
}

bool Message::sender(const char *s)
{
	return dbus_message_set_sender(_pvt->msg, s);
}

const char *Message::destination() const
{
	return dbus_message_get_destination(_pvt->msg);
}

bool Message::destination(const char *s)
{
	return dbus_message_set_destination(_pvt->msg, s);
}

bool Message::is_error() const
{
	return type() == DBUS_MESSAGE_TYPE_ERROR;
}

bool Message::is_signal(const char *interface, const char *member) const
{
	return dbus_message_is_signal(_pvt->msg, interface, member);
}

Tag *Message::tag() const
{
	return _pvt->tag;
}


MessageIter Message::writer()
{
	MessageIter iter(*this);
	dbus_message_iter_init_append(_pvt->msg, &iter._pvt->iter);
	return iter;
}

MessageIter Message::reader() const
{
	MessageIter iter(const_cast<Message &>(*this));
	dbus_message_iter_init(_pvt->msg, &iter._pvt->iter);
	return iter;
}

/*
*/

ErrorMessage::ErrorMessage()
{
	_pvt->msg = dbus_message_new(DBUS_MESSAGE_TYPE_ERROR);
}

ErrorMessage::ErrorMessage(const Message &to_reply, const char *name, const char *message)
{
	_pvt->msg = dbus_message_new_error(to_reply._pvt->msg, name, message);
}

bool ErrorMessage::operator == (const ErrorMessage &m) const
{
	return dbus_message_is_error(_pvt->msg, m.name());
}

const char *ErrorMessage::name() const
{
	return dbus_message_get_error_name(_pvt->msg);
}

bool ErrorMessage::name(const char *n)
{
	return dbus_message_set_error_name(_pvt->msg, n);
}

/*
*/

SignalMessage::SignalMessage(const char *name)
{
	_pvt->msg = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
	member(name);
}

SignalMessage::SignalMessage(const char *path, const char *interface, const char *name)
{
	_pvt->msg = dbus_message_new_signal(path, interface, name);
}

bool SignalMessage::operator == (const SignalMessage &m) const
{
	return dbus_message_is_signal(_pvt->msg, m.interface(), m.member());
}

const char *SignalMessage::interface() const
{
	return dbus_message_get_interface(_pvt->msg);
}

bool SignalMessage::interface(const char *i)
{
	return dbus_message_set_interface(_pvt->msg, i);
}

const char *SignalMessage::member() const
{
	return dbus_message_get_member(_pvt->msg);
}

bool SignalMessage::member(const char *m)
{
	return dbus_message_set_member(_pvt->msg, m);
}

const char *SignalMessage::path() const
{
	return dbus_message_get_path(_pvt->msg);
}

char ** SignalMessage::path_split() const
{
	char ** p;
	dbus_message_get_path_decomposed(_pvt->msg, &p);	//todo: return as a std::vector ?
	return p;
}

bool SignalMessage::path(const char *p)
{
	return dbus_message_set_path(_pvt->msg, p);
}

/*
*/

CallMessage::CallMessage()
{
	_pvt->msg = dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_CALL);
}

CallMessage::CallMessage(const char *dest, const char *path, const char *iface, const char *method)
{
	_pvt->msg = dbus_message_new_method_call(dest, path, iface, method);
}

bool CallMessage::operator == (const CallMessage &m) const
{
	return dbus_message_is_method_call(_pvt->msg, m.interface(), m.member());
}

const char *CallMessage::interface() const
{
	return dbus_message_get_interface(_pvt->msg);
}

bool CallMessage::interface(const char *i)
{
	return dbus_message_set_interface(_pvt->msg, i);
}

const char *CallMessage::member() const
{
	return dbus_message_get_member(_pvt->msg);
}

bool CallMessage::member(const char *m)
{
	return dbus_message_set_member(_pvt->msg, m);
}

const char *CallMessage::path() const
{
	return dbus_message_get_path(_pvt->msg);
}

char ** CallMessage::path_split() const
{
	char ** p;
	dbus_message_get_path_decomposed(_pvt->msg, &p);
	return p;
}

bool CallMessage::path(const char *p)
{
	return dbus_message_set_path(_pvt->msg, p);
}

const char *CallMessage::signature() const
{
	return dbus_message_get_signature(_pvt->msg);
}

/*
 */

TagMessage::TagMessage(Tag *tag)
{
	_pvt->tag = tag;
}

/*
*/

ReturnMessage::ReturnMessage(const CallMessage &callee)
{
	_pvt = new Private(dbus_message_new_method_return(callee._pvt->msg));
}

const char *ReturnMessage::signature() const
{
	return dbus_message_get_signature(_pvt->msg);
}
