/*
 *
 *  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
 *
 */


#ifndef __DBUSXX_TYPES_H
#define __DBUSXX_TYPES_H

#include <stdint.h>
#include <string>
#include <vector>
#include <map>

#include "api.h"
#include "util.h"
#include "message.h"
#include "error.h"

namespace DBus {

struct DXXAPI Path : public std::string
{ 
	Path() {}
	Path(const std::string &s) : std::string(s) {}
	Path(const char *c) : std::string(c) {}
	Path &operator = (std::string &s)
	{
		std::string::operator = (s);
		return *this;
	}
};

struct DXXAPI Signature : public std::string
{ 
	Signature() {}
	Signature(const std::string &s) : std::string(s) {}
	Signature(const char *c) : std::string(c) {}
	Signature &operator = (std::string &s)
	{
		std::string::operator = (s);
		return *this;
	}
};

class DXXAPI FileDescriptor
{
public:
	FileDescriptor() : _fd(-1) {}
	FileDescriptor(int n) : _fd(n) {}
	FileDescriptor &operator = (int fd)
	{
		_fd = fd;
		return *this;
	}
	int get() const { return _fd; }
private:
	int _fd;
};

struct DXXAPI Invalid {};

class DXXAPI Variant
{
public:

	Variant();

	Variant(MessageIter &it);

	Variant &operator = (const Variant &v);

	const Signature signature() const;

	void clear();

	MessageIter reader() const
	{
		return _msg.reader();
	}

	MessageIter writer()
	{
		return _msg.writer();
	}

	template <typename T>
	operator T() const;

private:

	Message _msg;
};

template <
	typename T1,
	typename T2 = Invalid,
	typename T3 = Invalid,
	typename T4 = Invalid,
	typename T5 = Invalid,
	typename T6 = Invalid,
	typename T7 = Invalid,
	typename T8 = Invalid	// who needs more than eight?
>
struct Struct
{
	T1 _1; T2 _2; T3 _3; T4 _4; T5 _5; T6 _6; T7 _7; T8 _8; 
};

template<typename K, typename V>
inline bool dict_has_key(const std::map<K,V>& map, const K &key)
{
	return map.find(key) != map.end();
}

template <typename T>
struct type
{
	static std::string sig()
	{
		throw ErrorInvalidArgs("unknown type");
		return "";
	}
};

template <> struct type<Variant>        { static std::string sig(){ return "v"; } };
template <> struct type<uint8_t>        { static std::string sig(){ return "y"; } };
template <> struct type<bool>           { static std::string sig(){ return "b"; } };
template <> struct type<int16_t>        { static std::string sig(){ return "n"; } };
template <> struct type<uint16_t>       { static std::string sig(){ return "q"; } };
template <> struct type<int32_t>        { static std::string sig(){ return "i"; } };
template <> struct type<uint32_t>       { static std::string sig(){ return "u"; } };
template <> struct type<int64_t>        { static std::string sig(){ return "x"; } };
template <> struct type<uint64_t>       { static std::string sig(){ return "t"; } };
template <> struct type<double>         { static std::string sig(){ return "d"; } };
template <> struct type<std::string>    { static std::string sig(){ return "s"; } };
template <> struct type<Path>           { static std::string sig(){ return "o"; } };
template <> struct type<Signature>      { static std::string sig(){ return "g"; } };
template <> struct type<Invalid>        { static std::string sig(){ return "";  } };

template <typename E> 
struct type< std::vector<E> >
{ static std::string sig(){ return "a" + type<E>::sig(); } };

template <typename K, typename V>
struct type< std::map<K,V> >
{ static std::string sig(){ return "a{" + type<K>::sig() + type<V>::sig() + "}"; } };

template <
	typename T1,
	typename T2,
	typename T3,
	typename T4,
	typename T5,
	typename T6,
	typename T7,
	typename T8 // who needs more than eight?
>
struct type< Struct<T1,T2,T3,T4,T5,T6,T7,T8> >
{ 
	static std::string sig()
	{ 
		return "("
			+ type<T1>::sig()
			+ type<T2>::sig()
			+ type<T3>::sig()
			+ type<T4>::sig()
			+ type<T5>::sig()
			+ type<T6>::sig()
			+ type<T7>::sig()
			+ type<T8>::sig()
			+ ")";
	}
};

extern DXXAPI DBus::MessageIter &operator << (DBus::MessageIter &iter, const DBus::Variant &val);

inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const DBus::Invalid &)
{
	return iter;
}

inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const uint8_t &val)
{
	iter.append_byte(val);
	return iter;
}

inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const bool &val)
{
	iter.append_bool(val);
	return iter;
}

inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const int16_t& val)
{
	iter.append_int16(val);
	return iter;
}

inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const uint16_t& val)
{
	iter.append_uint16(val);
	return iter;
}

inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const int32_t& val)
{
	iter.append_int32(val);
	return iter;
}

inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const uint32_t& val)
{
	iter.append_uint32(val);
	return iter;
}

inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const int64_t& val)
{
	iter.append_int64(val);
	return iter;
}

inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const uint64_t& val)
{
	iter.append_uint64(val);
	return iter;
}

inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const double &val)
{
	iter.append_double(val);
	return iter;
}

inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const std::string &val)
{
	iter.append_string(val.c_str());
	return iter;
}

inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const DBus::Path &val)
{
	iter.append_path(val.c_str());
	return iter;
}

inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const DBus::Signature &val)
{
	iter.append_signature(val.c_str());
	return iter;
}

inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const DBus::FileDescriptor &val)
{
	iter.append_fd(val.get());
	return iter;
}

template<typename E>
inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const std::vector<E>& val)
{
	const std::string sig = DBus::type<E>::sig();
	DBus::MessageIter ait = iter.new_array(sig.c_str());

	typename std::vector<E>::const_iterator vit;
	for (vit = val.begin(); vit != val.end(); ++vit)
	{
		ait << *vit;
	}

	iter.close_container(ait);
	return iter;
}

template<>
inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const std::vector<uint8_t>& val)
{
	DBus::MessageIter ait = iter.new_array("y");
	if (!val.empty())
		ait.append_array('y', &val.front(), val.size());
	iter.close_container(ait);
	return iter;
}

template<typename K, typename V>
inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const std::map<K,V>& val)
{
	const std::string sig = "{" + DBus::type<K>::sig() + DBus::type<V>::sig() + "}";
	DBus::MessageIter ait = iter.new_array(sig.c_str());

	typename std::map<K,V>::const_iterator mit;
	for (mit = val.begin(); mit != val.end(); ++mit)
	{
		DBus::MessageIter eit = ait.new_dict_entry();

		eit << mit->first << mit->second;

		ait.close_container(eit);
	}

	iter.close_container(ait);
	return iter;
}

template <
	typename T1,
	typename T2,
	typename T3,
	typename T4,
	typename T5,
	typename T6,
	typename T7,
	typename T8
>
inline DBus::MessageIter &operator << (DBus::MessageIter &iter, const DBus::Struct<T1,T2,T3,T4,T5,T6,T7,T8>& val)
{
/*	const std::string sig = 
		DBus::type<T1>::sig() + DBus::type<T2>::sig() + DBus::type<T3>::sig() + DBus::type<T4>::sig() +
		DBus::type<T5>::sig() + DBus::type<T6>::sig() + DBus::type<T7>::sig() + DBus::type<T8>::sig();
*/
	DBus::MessageIter sit = iter.new_struct(/*sig.c_str()*/);

	sit << val._1 << val._2 << val._3 << val._4 << val._5 << val._6 << val._7 << val._8;

	iter.close_container(sit);

	return iter;
}

/*
 */

inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, DBus::Invalid &)
{
	return iter;
}

inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, uint8_t &val)
{
	val = iter.get_byte();
	return ++iter;
}

inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, bool &val)
{
	val = iter.get_bool();
	return ++iter;
}

inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, int16_t& val)
{
	val = iter.get_int16();
	return ++iter;
}

inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, uint16_t& val)
{
	val = iter.get_uint16();
	return ++iter;
}

inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, int32_t& val)
{
	val = iter.get_int32();
	return ++iter;
}

inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, uint32_t& val)
{
	val = iter.get_uint32();
	return ++iter;
}

inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, int64_t& val)
{
	val = iter.get_int64();
	return ++iter;
}

inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, uint64_t& val)
{
	val = iter.get_uint64();
	return ++iter;
}

inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, double &val)
{
	val = iter.get_double();
	return ++iter;
}

inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, std::string &val)
{
	val = iter.get_string();
	return ++iter;
}

inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, DBus::Path &val)
{
	val = iter.get_path();
	return ++iter;
}

inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, DBus::Signature &val)
{
	val = iter.get_signature();
	return ++iter;
}

inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, DBus::FileDescriptor &val)
{
	val = iter.get_fd();
	return ++iter;
}

extern DXXAPI DBus::MessageIter &operator >> (DBus::MessageIter &iter, DBus::Variant &val);

template<typename E>
inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, std::vector<E>& val)
{
	if (!iter.is_array())
		throw DBus::ErrorInvalidArgs("array expected");

	DBus::MessageIter ait = iter.recurse();

	while (!ait.at_end())
	{
		E elem;

		ait >> elem;

		val.push_back(elem);
	}
	return ++iter;
}

template<>
inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, std::vector<uint8_t>& val)
{
	if (!iter.is_array())
		throw DBus::ErrorInvalidArgs("array expected");

	if (iter.array_type() != 'y')
		throw DBus::ErrorInvalidArgs("byte-array expected");

	DBus::MessageIter ait = iter.recurse();

	uint8_t *array;
	size_t length = ait.get_array(&array);

	val.insert(val.end(), array, array+length);

	return ++iter;
}

template<typename K, typename V>
inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, std::map<K,V>& val)
{
	if (!iter.is_dict())
		throw DBus::ErrorInvalidArgs("dictionary value expected");

	DBus::MessageIter mit = iter.recurse();

	while (!mit.at_end())
	{
		K key; V value;

		DBus::MessageIter eit = mit.recurse();

		eit >> key >> value;

		val[key] = value;

		++mit;
	}

	return ++iter;
}

template <
	typename T1,
	typename T2,
	typename T3,
	typename T4,
	typename T5,
	typename T6,
	typename T7,
	typename T8
>
inline DBus::MessageIter &operator >> (DBus::MessageIter &iter, DBus::Struct<T1,T2,T3,T4,T5,T6,T7,T8>& val)
{
	DBus::MessageIter sit = iter.recurse();

	sit >> val._1 >> val._2 >> val._3 >> val._4 >> val._5 >> val._6 >> val._7 >> val._8;

	return ++iter;
}

template <typename T>
inline DBus::Variant::operator T() const
{
	T cast;
	DBus::MessageIter ri = _msg.reader();
	ri >> cast;
	return cast;
}

} /* namespace DBus */

#endif//__DBUSXX_TYPES_H
