/*
 *
 *  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++/object.h>
#include "internalerror.h"

#include <cstring>
#include <map>
#include <dbus/dbus.h>

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

using namespace DBus;

Object::Object(Connection &conn, const Path &path, const char *service)
  : _conn(conn), _path(path), _service(service ? service : ""), _default_timeout(-1)
{
}

Object::~Object()
{
}

void Object::set_timeout(int new_timeout)
{
  debug_log("%s: %d millies", __PRETTY_FUNCTION__, new_timeout);
  if (new_timeout < 0 && new_timeout != -1)
    throw ErrorInvalidArgs("Bad timeout, cannot set it");
  _default_timeout = new_timeout;
}

struct ObjectAdaptor::Private
{
  static void unregister_function_stub(DBusConnection *, void *);
  static DBusHandlerResult message_function_stub(DBusConnection *, DBusMessage *, void *);
};

static DBusObjectPathVTable _vtable =
{
  ObjectAdaptor::Private::unregister_function_stub,
  ObjectAdaptor::Private::message_function_stub,
  NULL, NULL, NULL, NULL
};

void ObjectAdaptor::Private::unregister_function_stub(DBusConnection *conn, void *data)
{
  //TODO: what do we have to do here ?
}

DBusHandlerResult ObjectAdaptor::Private::message_function_stub(DBusConnection *, DBusMessage *dmsg, void *data)
{
  ObjectAdaptor *o = static_cast<ObjectAdaptor *>(data);

  if (o)
  {
    Message msg(new Message::Private(dmsg));

    debug_log("in object %s", o->path().c_str());
    debug_log(" got message #%d from %s to %s",
              msg.serial(),
              msg.sender(),
              msg.destination()
             );

    return o->handle_message(msg)
           ? DBUS_HANDLER_RESULT_HANDLED
           : DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
  }
  else
  {
    return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
  }
}

typedef std::map<Path, ObjectAdaptor *> ObjectAdaptorTable;
static ObjectAdaptorTable _adaptor_table;

ObjectAdaptor *ObjectAdaptor::from_path(const Path &path)
{
  ObjectAdaptorTable::iterator ati = _adaptor_table.find(path);

  if (ati != _adaptor_table.end())
    return ati->second;

  return NULL;
}

ObjectAdaptorPList ObjectAdaptor::from_path_prefix(const std::string &prefix)
{
  ObjectAdaptorPList ali;

  ObjectAdaptorTable::iterator ati = _adaptor_table.begin();

  size_t plen = prefix.length();

  while (ati != _adaptor_table.end())
  {
    if (!strncmp(ati->second->path().c_str(), prefix.c_str(), plen))
      ali.push_back(ati->second);

    ++ati;
  }

  return ali;
}

ObjectPathList ObjectAdaptor::child_nodes_from_prefix(const std::string &prefix)
{
  ObjectPathList ali;

  ObjectAdaptorTable::iterator ati = _adaptor_table.begin();

  size_t plen = prefix.length();

  while (ati != _adaptor_table.end())
  {
    if (!strncmp(ati->second->path().c_str(), prefix.c_str(), plen))
    {
      std::string p = ati->second->path().substr(plen);
      p = p.substr(0, p.find('/'));
      ali.push_back(p);
    }
    ++ati;
  }

  ali.sort();
  ali.unique();

  return ali;
}

ObjectAdaptor::ObjectAdaptor(Connection &conn, const Path &path)
  : Object(conn, path, conn.unique_name())
{
  register_obj();
}

ObjectAdaptor::~ObjectAdaptor()
{
  unregister_obj(false);
}

void ObjectAdaptor::register_obj()
{
  debug_log("registering local object %s", path().c_str());

  if (!dbus_connection_register_object_path(conn()._pvt->conn, path().c_str(), &_vtable, this))
  {
    throw ErrorNoMemory("unable to register object path");
  }

  _adaptor_table[path()] = this;
}

void ObjectAdaptor::unregister_obj(bool)
{
  _adaptor_table.erase(path());

  debug_log("unregistering local object %s", path().c_str());

  dbus_connection_unregister_object_path(conn()._pvt->conn, path().c_str());
}

void ObjectAdaptor::_emit_signal(SignalMessage &sig)
{
  sig.path(path().c_str());

  conn().send(sig);
}

struct ReturnLaterError
{
  const Tag *tag;
};

bool ObjectAdaptor::handle_message(const Message &msg)
{
  switch (msg.type())
  {
  case DBUS_MESSAGE_TYPE_METHOD_CALL:
  {
    const CallMessage &cmsg = reinterpret_cast<const CallMessage &>(msg);
    const char *member      = cmsg.member();
    const char *interface   = cmsg.interface();

    debug_log(" invoking method %s.%s", interface, member);

    InterfaceAdaptor *ii = find_interface(interface);
    if (ii)
    {
      try
      {
        Message ret = ii->dispatch_method(cmsg);
        conn().send(ret);
      }
      catch (Error &e)
      {
        ErrorMessage em(cmsg, e.name(), e.message());
        conn().send(em);
      }
      catch (ReturnLaterError &rle)
      {
        _continuations[rle.tag] = new Continuation(conn(), cmsg, rle.tag);
      }
      return true;
    }
    else
    {
      return false;
    }
  }
  default:
  {
    return false;
  }
  }
}

void ObjectAdaptor::return_later(const Tag *tag)
{
  ReturnLaterError rle = { tag };
  throw rle;
}

void ObjectAdaptor::return_now(Continuation *ret)
{
  ret->_conn.send(ret->_return);

  ContinuationMap::iterator di = _continuations.find(ret->_tag);

  delete di->second;

  _continuations.erase(di);
}

void ObjectAdaptor::return_error(Continuation *ret, const Error error)
{
  ret->_conn.send(ErrorMessage(ret->_call, error.name(), error.message()));

  ContinuationMap::iterator di = _continuations.find(ret->_tag);

  delete di->second;

  _continuations.erase(di);
}

ObjectAdaptor::Continuation *ObjectAdaptor::find_continuation(const Tag *tag)
{
  ContinuationMap::iterator di = _continuations.find(tag);

  return di != _continuations.end() ? di->second : NULL;
}

ObjectAdaptor::Continuation::Continuation(Connection &conn, const CallMessage &call, const Tag *tag)
  : _conn(conn), _call(call), _return(_call), _tag(tag)
{
  _writer = _return.writer(); //todo: verify
}

/*
*/

ObjectProxy::ObjectProxy(Connection &conn, const Path &path, const char *service)
  : Object(conn, path, service)
{
  register_obj();
}

ObjectProxy::~ObjectProxy()
{
  unregister_obj(false);
}

void ObjectProxy::register_obj()
{
  debug_log("registering remote object %s", path().c_str());

  _filtered = new Callback<ObjectProxy, bool, const Message &>(this, &ObjectProxy::handle_message);

  conn().add_filter(_filtered);

  InterfaceProxyTable::const_iterator ii = _interfaces.begin();
  while (ii != _interfaces.end())
  {
    std::string im = "type='signal',interface='" + ii->first + "',path='" + path() + "'";
    conn().add_match(im.c_str());
    ++ii;
  }
}

void ObjectProxy::unregister_obj(bool throw_on_error)
{
  debug_log("unregistering remote object %s", path().c_str());

  InterfaceProxyTable::const_iterator ii = _interfaces.begin();
  while (ii != _interfaces.end())
  {
    std::string im = "type='signal',interface='" + ii->first + "',path='" + path() + "'";
    conn().remove_match(im.c_str(), throw_on_error);
    ++ii;
  }
  conn().remove_filter(_filtered);
}

Message ObjectProxy::_invoke_method(CallMessage &call)
{
  if (call.path() == NULL)
    call.path(path().c_str());

  if (call.destination() == NULL)
    call.destination(service().c_str());

  return conn().send_blocking(call, get_timeout());
}

bool ObjectProxy::_invoke_method_noreply(CallMessage &call)
{
  if (call.path() == NULL)
    call.path(path().c_str());

  if (call.destination() == NULL)
    call.destination(service().c_str());

  return conn().send(call);
}

bool ObjectProxy::handle_message(const Message &msg)
{
  switch (msg.type())
  {
  case DBUS_MESSAGE_TYPE_SIGNAL:
  {
    const SignalMessage &smsg = reinterpret_cast<const SignalMessage &>(msg);
    const char *interface	= smsg.interface();
    const char *member	= smsg.member();
    const char *objpath	= smsg.path();

    if (objpath != path()) return false;

    debug_log("filtered signal %s(in %s) from %s to object %s",
              member, interface, msg.sender(), objpath);

    InterfaceProxy *ii = find_interface(interface);
    if (ii)
    {
      return ii->dispatch_signal(smsg);
    }
    else
    {
      return false;
    }
  }
  default:
  {
    return false;
  }
  }
}
