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

/* Project */
#include <dbus-c++/eventloop-integration.h>
#include <dbus-c++/debug.h>
#include <dbus-c++/pipe.h>

/* DBus */
#include <dbus/dbus.h>

/* STD */
#include <string.h>
#include <cassert>
#include <sys/poll.h>
#include <fcntl.h>

using namespace DBus;
using namespace std;

BusTimeout::BusTimeout(Timeout::Internal *ti, BusDispatcher *bd)
  : Timeout(ti), DefaultTimeout(Timeout::interval(), true, bd)
{
  DefaultTimeout::enabled(Timeout::enabled());
}

void BusTimeout::toggle()
{
  debug_log("timeout %p toggled (%s)", this, Timeout::enabled() ? "on" : "off");

  DefaultTimeout::enabled(Timeout::enabled());
}

BusWatch::BusWatch(Watch::Internal *wi, BusDispatcher *bd)
  : Watch(wi), DefaultWatch(Watch::descriptor(), 0, bd)
{
  int flags = POLLHUP | POLLERR;

  if (Watch::flags() & DBUS_WATCH_READABLE)
    flags |= POLLIN;
  if (Watch::flags() & DBUS_WATCH_WRITABLE)
    flags |= POLLOUT;

  DefaultWatch::flags(flags);
  DefaultWatch::enabled(Watch::enabled());
}

void BusWatch::toggle()
{
  debug_log("watch %p toggled (%s)", this, Watch::enabled() ? "on" : "off");

  DefaultWatch::enabled(Watch::enabled());
}

BusDispatcher::BusDispatcher() :
  _running(false)
{
  // pipe to create a new fd used to unlock a dispatcher at any
  // moment (used by leave function)
  int ret = pipe(_pipe);
  if (ret == -1) throw Error("PipeError:errno", toString(errno).c_str());

  _fdunlock[0] = _pipe[0];
  _fdunlock[1] = _pipe[1];
}

void BusDispatcher::enter()
{
  debug_log("entering dispatcher %p", this);

  _running = true;

  while (_running)
  {
    do_iteration();

    for (std::list <Pipe *>::iterator p_it = pipe_list.begin();
         p_it != pipe_list.end();
         ++p_it)
    {
      Pipe *read_pipe = *p_it;
      char buffer[1024]; // TODO: should be max pipe size
      unsigned int nbytes = 0;

      while (read_pipe->read(buffer, nbytes) > 0)
      {
        read_pipe->_handler(read_pipe->_data, buffer, nbytes);
      }

    }
  }

  debug_log("leaving dispatcher %p", this);
}

void BusDispatcher::leave()
{
  _running = false;

  int ret = write(_fdunlock[1], "exit", strlen("exit"));
  if (ret == -1) throw Error("WriteError:errno", toString(errno).c_str());

  close(_fdunlock[1]);
  close(_fdunlock[0]);
}

Pipe *BusDispatcher::add_pipe(void(*handler)(const void *data, void *buffer, unsigned int nbyte), const void *data)
{
  Pipe *new_pipe = new Pipe(handler, data);
  pipe_list.push_back(new_pipe);

  return new_pipe;
}

void BusDispatcher::del_pipe(Pipe *pipe)
{
  pipe_list.remove(pipe);
  delete pipe;
}

void BusDispatcher::do_iteration()
{
  dispatch_pending();
  dispatch();
}

Timeout *BusDispatcher::add_timeout(Timeout::Internal *ti)
{
  BusTimeout *bt = new BusTimeout(ti, this);

  bt->expired = new Callback<BusDispatcher, void, DefaultTimeout &>(this, &BusDispatcher::timeout_expired);
  bt->data(bt);

  debug_log("added timeout %p (%s) (%d millies)",
            bt,
            ((Timeout *)bt)->enabled() ? "on" : "off",
            ((Timeout *)bt)->interval()
           );

  return bt;
}

void BusDispatcher::rem_timeout(Timeout *t)
{
  debug_log("removed timeout %p", t);

  delete t;
}

Watch *BusDispatcher::add_watch(Watch::Internal *wi)
{
  BusWatch *bw = new BusWatch(wi, this);

  bw->ready = new Callback<BusDispatcher, void, DefaultWatch &>(this, &BusDispatcher::watch_ready);
  bw->data(bw);

  debug_log("added watch %p (%s) fd=%d flags=%d",
            bw, ((Watch *)bw)->enabled() ? "on" : "off", ((Watch *)bw)->descriptor(), ((Watch *)bw)->flags());

  return bw;
}

void BusDispatcher::rem_watch(Watch *w)
{
  debug_log("removed watch %p", w);

  delete w;
}

void BusDispatcher::timeout_expired(DefaultTimeout &et)
{
  debug_log("timeout %p expired", &et);

  BusTimeout *timeout = reinterpret_cast<BusTimeout *>(et.data());

  timeout->handle();
}

void BusDispatcher::watch_ready(DefaultWatch &ew)
{
  BusWatch *watch = reinterpret_cast<BusWatch *>(ew.data());

  debug_log("watch %p ready, flags=%d state=%d",
            watch, ((Watch *)watch)->flags(), watch->state()
           );

  int flags = 0;

  if (watch->state() & POLLIN)
    flags |= DBUS_WATCH_READABLE;
  if (watch->state() & POLLOUT)
    flags |= DBUS_WATCH_WRITABLE;
  if (watch->state() & POLLHUP)
    flags |= DBUS_WATCH_HANGUP;
  if (watch->state() & POLLERR)
    flags |= DBUS_WATCH_ERROR;

  watch->handle(flags);
}

