/*
 * dbus.c - event loop dbus integration
 * Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#include "config.h"

#include <errno.h>
#include <stdio.h>
#include <stdint.h>
#include <time.h>
#include <unistd.h>

#include <dbus/dbus.h>
#include <event2/event.h>
#include "src/dbus.h"
#include "src/tlsdate.h"
#include "src/util.h"

static const char kServiceInterface[] = "org.torproject.tlsdate";
static const char kServicePath[] = "/org/torproject/tlsdate";
static const char kServiceSetTime[] = "SetTime";
static const char kServiceCanSetTime[] = "CanSetTime";
static const char kServiceLastSyncInfo[] = "LastSyncInfo";

#ifdef TLSDATED_MAIN
static const char kTimeUpdated[] = "TimeUpdated";
#endif

static
short
dbus_to_event (unsigned int flags)
{
  short events = 0;
  if (flags & DBUS_WATCH_READABLE)
    events |= EV_READ;
  if (flags & DBUS_WATCH_WRITABLE)
    events |= EV_WRITE;
  return events;
}

static
unsigned int
event_to_dbus (short events)
{
  unsigned int flags = 0;
  if (events & EV_READ)
    flags |= DBUS_WATCH_READABLE;
  if (events & EV_WRITE)
    flags |= DBUS_WATCH_WRITABLE;
  return flags;
}

static
void
watch_handler (evutil_socket_t fd, short what, void *arg)
{
  DBusWatch *watch = arg;
  struct dbus_event_data *data = dbus_watch_get_data (watch);
  unsigned int flags = event_to_dbus (what);
  dbus_connection_ref (data->state->conn);
  while (!dbus_watch_handle (watch, flags))
    {
      info ("dbus_watch_handle waiting for memory . . .");
      /* TODO(wad) this seems like a bad idea. */
      sleep (1);
    }
  while (dbus_connection_dispatch (data->state->conn) ==
         DBUS_DISPATCH_DATA_REMAINS);
  dbus_connection_unref (data->state->conn);
}

static
dbus_bool_t
add_watch (DBusWatch *watch, void *user_data)
{
  struct state *tlsdate_state = user_data;
  struct dbus_state *state = tlsdate_state->dbus;
  struct dbus_event_data *data;
  /* Don't add anything if it isn't active. */
  data = dbus_malloc0 (sizeof (struct dbus_event_data));
  if (!data)
    return FALSE;
  data->state = state;
  data->event = event_new (tlsdate_state->base,
                           dbus_watch_get_unix_fd (watch),
                           EV_PERSIST|dbus_to_event (dbus_watch_get_flags (watch)),
                           watch_handler,
                           watch);
  if (!data->event)
    {
      dbus_free (data);
      return FALSE;
    }
  event_priority_set (data->event, PRI_WAKE);

  dbus_watch_set_data (watch, data, dbus_free);
  if (!dbus_watch_get_enabled (watch))
    return TRUE;
  /* Only add the event if it is enabled. */
  if (event_add (data->event, NULL))
    {
      error ("Could not add a new watch!");
      event_free (data->event);
      dbus_free (data);
      return FALSE;
    }
  return TRUE;
}

static
void
remove_watch (DBusWatch *watch, void *user_data)
{
  struct dbus_event_data *data = dbus_watch_get_data (watch);
  /* TODO(wad) should this just be in a free_function? */
  if (data && data->event)
    {
      event_del (data->event);
      event_free (data->event);
    }
}

static
void
toggle_watch (DBusWatch *watch, void *user_data)
{
  struct dbus_event_data *data = dbus_watch_get_data (watch);
  if (!data || !data->event)  /* should not be possible */
    return;
  /* If the event is pending, then we have to remove it to
   * disable it or remove it before re-enabling it.
   */
  if (event_pending (data->event,
                     dbus_to_event (dbus_watch_get_flags (watch)), NULL))
    event_del (data->event);
  if (dbus_watch_get_enabled (watch))
    {
      event_add (data->event, NULL);
    }
}

static
void
timeout_handler (evutil_socket_t fd, short what, void *arg)
{
  DBusTimeout *t = arg;
  struct dbus_event_data *data = dbus_timeout_get_data (t);
  dbus_connection_ref (data->state->conn);
  dbus_timeout_handle (t);
  dbus_connection_unref (data->state->conn);
}

static
dbus_bool_t
add_timeout (DBusTimeout *t, void *user_data)
{
  struct state *tlsdate_state = user_data;
  struct dbus_state *state = tlsdate_state->dbus;
  struct dbus_event_data *data;
  int ms = dbus_timeout_get_interval (t);
  struct timeval interval;
  data = dbus_malloc0 (sizeof (struct dbus_event_data));
  if (!data)
    return FALSE;
  interval.tv_sec = ms / 1000;
  interval.tv_usec = (ms % 1000) * 1000;
  data->state = state;
  data->event = event_new (tlsdate_state->base,
                           -1,
                           EV_TIMEOUT|EV_PERSIST,
                           timeout_handler,
                           t);
  if (!data->event)
    {
      dbus_free (data);
      return FALSE;
    }
  event_priority_set (data->event, PRI_WAKE);
  dbus_timeout_set_data (t, data, dbus_free);
  /* Only add it to the queue if it is enabled. */
  if (!dbus_timeout_get_enabled (t))
    return TRUE;
  if (event_add (data->event, &interval))
    {
      error ("Could not add a new timeout!");
      event_free (data->event);
      dbus_free (data);
      return FALSE;
    }
  return TRUE;
}

static
void
remove_timeout (DBusTimeout *t, void *user_data)
{
  struct dbus_event_data *data = dbus_timeout_get_data (t);
  if (data && data->event)
    {
      event_del (data->event);
      event_free (data->event);
    }
}

static
void
toggle_timeout (DBusTimeout *t, void *user_data)
{
  struct dbus_event_data *data = dbus_timeout_get_data (t);
  int ms = dbus_timeout_get_interval (t);
  struct timeval interval;
  /* If the event is pending, then we have to remove it to
   * disable it or remove it before re-enabling it.
   */
  if (evtimer_pending (data->event, NULL))
    event_del (data->event);
  if (dbus_timeout_get_enabled (t))
    {
      interval.tv_sec = ms / 1000;
      interval.tv_usec = (ms % 1000) * 1000;
      event_add (data->event, &interval);
    }
}

#ifdef TLSDATED_MAIN
void
dbus_announce (struct state *global_state)
{
  struct dbus_state *state = global_state->dbus;
  DBusConnection *conn = state->conn;
  DBusMessage *msg;
  uint32_t ignored;
  const char *sync_type = sync_type_str (global_state->last_sync_type);
  msg = dbus_message_new_signal (kServicePath, kServiceInterface, kTimeUpdated);
  if (!msg)
    {
      error ("[dbus] could not allocate new announce signal");
      return;
    }
  if (!dbus_message_append_args (msg,
                                 DBUS_TYPE_STRING, &sync_type,
                                 DBUS_TYPE_INVALID))
    {
      error ("[dbus] could not allocate new announce args");
      return;
    }
  if (!dbus_connection_send (conn, msg, &ignored))
    {
      error ("[dbus] could not send announce signal");
      return;
    }
}
#endif

static
DBusHandlerResult
send_time_reply (DBusConnection *connection,
                 DBusMessage *message,
                 dbus_uint32_t code)
{
   DBusMessage *reply;
   DBusMessageIter args;
   dbus_uint32_t serial = dbus_message_get_serial (message);

   reply = dbus_message_new_method_return (message);
   if (!reply)
     {
       error ("[dbus] no memory to reply to SetTime");
       return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
     }

  if (!dbus_message_set_reply_serial (reply, serial))
    {
      error ("[dbus] no memory to set serial for reply to SetTime");
      dbus_message_unref (reply);
      return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
    }

  dbus_message_iter_init_append (reply, &args);
  if (!dbus_message_iter_append_basic (&args, DBUS_TYPE_UINT32, &code))
    {
      error ("[dbus] no memory to add reply args to SetTime");
      dbus_message_unref (reply);
      return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
    }

  if (!dbus_connection_send (connection, reply, &serial))
   {
      error ("[dbus] unable to send SetTime reply");
      dbus_message_unref (reply);
      return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
   }
  dbus_connection_flush (connection);
  dbus_message_unref (reply);
  return DBUS_HANDLER_RESULT_HANDLED;
}

static
DBusHandlerResult
send_can_reply (DBusConnection *connection,
                DBusMessage *message,
                dbus_bool_t allowed)
{
  DBusMessage *reply;
  DBusMessageIter args;
  dbus_uint32_t serial = dbus_message_get_serial (message);

  reply = dbus_message_new_method_return (message);
  if (!reply)
    {
      error ("[dbus] no memory to reply to CanSetTime");
      return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
    }

  if (!dbus_message_set_reply_serial (reply, serial))
    {
      error ("[dbus] no memory to set serial for reply to CanSetTime");
      dbus_message_unref (reply);
      return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
    }

  dbus_message_iter_init_append (reply, &args);
  if (!dbus_message_iter_append_basic (&args, DBUS_TYPE_BOOLEAN, &allowed))
    {
      error ("[dbus] no memory to add reply args to CanSetTime");
      dbus_message_unref (reply);
      return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
    }

  if (!dbus_connection_send (connection, reply, &serial))
   {
      error ("[dbus] unable to send CanSetTime reply");
      dbus_message_unref (reply);
      return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
   }
  dbus_connection_flush (connection);
  dbus_message_unref (reply);
  return DBUS_HANDLER_RESULT_HANDLED;
}

/* Returns 0 if time cannot be set, and 1 otherwise. */
static
int
can_set_time (struct state *state)
{
  time_t delta = state->clock_delta;
  /* Force a synchronization check. */
  if (check_continuity (&delta) > 0)
    {
      info ("[event:%s] clock delta desync detected (%ld != %ld)",
            __func__, state->clock_delta, delta);
      delta = state->clock_delta = 0;
      invalidate_time (state);
    }
  /* Only use the time if we're not synchronized. */
  return !state->clock_delta;
}

static
DBusHandlerResult
handle_set_time (DBusConnection *connection,
                 DBusMessage *message,
                 struct state *state)
{
  DBusMessageIter iter;
  DBusError error;
  dbus_int64_t requested_time = 0;
  debug ("[event:%s]: fired", __func__);
  dbus_error_init (&error);

  /* Expects DBUS_TYPE_INT64:<time_t> */
  if (!dbus_message_iter_init (message, &iter))
    return send_time_reply (connection, message, SET_TIME_BAD_CALL);
  if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_INT64)
    return send_time_reply (connection, message, SET_TIME_BAD_CALL);
  dbus_message_iter_get_basic (&iter, &requested_time);
  if (!is_sane_time ((time_t) requested_time))
    {
      error ("event:%s] invalid time from user: %ld", __func__,
             (time_t) requested_time);
      return send_time_reply (connection, message, SET_TIME_INVALID);
    }
  if (!can_set_time (state))
    {
      info ("[event:%s]: time is already synchronized.", __func__);
      return send_time_reply (connection, message, SET_TIME_NOT_ALLOWED);
    }

  state->last_time = requested_time;
  state->last_sync_type = SYNC_TYPE_PLATFORM;
  trigger_event (state, E_SAVE, -1);
  /* Kick off a network sync for good measure. */
  action_kickoff_time_sync (-1, EV_TIMEOUT, state);

  return send_time_reply (connection, message, SET_TIME_OK);
}

static
DBusHandlerResult
handle_can_set_time (DBusConnection *connection,
                     DBusMessage *message,
                     struct state *state)
{
  debug ("[event:%s]: fired", __func__);
  return send_can_reply (connection, message, can_set_time (state));
}

static
DBusHandlerResult
handle_last_sync_info (DBusConnection *connection,
                       DBusMessage *message,
                       struct state *state)
{
  DBusMessage *reply;
  DBusMessageIter args;
  dbus_uint32_t serial = dbus_message_get_serial (message);
  dbus_bool_t net_synced = !!state->clock_delta;
  const char *sync = sync_type_str (state->last_sync_type);
  int64_t t = state->last_time;

  debug ("[dbus]: handler fired");
  reply = dbus_message_new_method_return (message);
  if (!reply)
    {
      error ("[dbus] no memory to reply to LastSyncInfo");
      return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
    }

  if (!dbus_message_set_reply_serial (reply, serial))
    {
     error ("[dbus] no memory to set serial for reply to LastSyncInfo");
     dbus_message_unref (reply);
      return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
    }

  dbus_message_iter_init_append (reply, &args);
  if (!dbus_message_iter_append_basic (&args, DBUS_TYPE_BOOLEAN, &net_synced))
    {
      error ("[dbus] no memory to add reply args to LastSyncInfo");
      dbus_message_unref (reply);
      return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
    }
  if (!dbus_message_iter_append_basic (&args, DBUS_TYPE_STRING, &sync))
    {
      error ("[dbus] no memory to add reply args to LastSyncInfo");
      dbus_message_unref (reply);
      return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
    }
  if (!dbus_message_iter_append_basic (&args, DBUS_TYPE_INT64, &t))
    {
      error ("[dbus] no memory to add reply args to LastSyncInfo");
      dbus_message_unref (reply);
      return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
    }

  if (!dbus_connection_send (connection, reply, &serial))
   {
      error ("[dbus] unable to send LastSyncInfo reply");
      dbus_message_unref (reply);
      return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
   }
  dbus_connection_flush (connection);
  dbus_message_unref (reply);
  return DBUS_HANDLER_RESULT_HANDLED;
}

static
void
unregister_service (DBusConnection *conn, void *data)
{
  info ("dbus service has been unregistered");
}

static
DBusHandlerResult
service_dispatch (DBusConnection *conn, DBusMessage *msg, void *data)
{
  struct state *state = data;
  const char *interface;
  const char *method;

  debug ("[dbus] service dispatcher called");
  if (dbus_message_get_type (msg) != DBUS_MESSAGE_TYPE_METHOD_CALL)
    return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;

  interface = dbus_message_get_interface (msg);
  method = dbus_message_get_member (msg);
  if (!interface || !method)
    {
      debug ("[dbus] service request fired with bogus data");
      /* Consume it */
      return DBUS_HANDLER_RESULT_HANDLED;
    }
  if (strcmp (interface, kServiceInterface))
    {
      debug ("[dbus] invalid interface supplied");
      return DBUS_HANDLER_RESULT_HANDLED;
    }
  if (!strcmp (method, kServiceSetTime))
    return handle_set_time (conn, msg, state);
  else if (!strcmp (method, kServiceCanSetTime))
    return handle_can_set_time (conn, msg, state);
  else if (!strcmp (method, kServiceLastSyncInfo))
    return handle_last_sync_info (conn, msg, state);
  debug ("[dbus] invalid method supplied");
  return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}

static DBusObjectPathVTable service_vtable = {
    .unregister_function = unregister_service,
    .message_function = service_dispatch,
};

int
init_dbus (struct state *tlsdate_state)
{
  DBusError error;
  dbus_error_init (&error);
  struct dbus_state *state = calloc (1, sizeof (struct dbus_state));
  if (!state)
    return 1;
  tlsdate_state->dbus = state;
  state->conn = dbus_bus_get (DBUS_BUS_SYSTEM, &error);
  if (state->conn == NULL || dbus_error_is_set (&error))
    {
      error ("[dbus] error when connecting to the bus: %s",
             error.message);
      goto err;
    }
  if (!dbus_connection_set_timeout_functions (state->conn, add_timeout,
      remove_timeout, toggle_timeout, tlsdate_state, dbus_free))
    {
      error ("[dbus] dbus_connection_set_timeout_functions failed");
      /* TODO(wad) disconnect from DBus */
      goto err;
    }
  if (!dbus_connection_set_watch_functions (state->conn, add_watch,
      remove_watch, toggle_watch, tlsdate_state, dbus_free))
    {
      error ("[dbus] dbus_connection_set_watch_functions failed");
      goto err;
    }
  if (!dbus_bus_request_name (state->conn, kServiceInterface, 0, &error) ||
      dbus_error_is_set (&error))
    {
      error ("[dbus] failed to get name: %s", error.message);
      goto err;
    }

  /* Setup the vtable for dispatching incoming messages. */
  if (dbus_connection_register_object_path (
          state->conn, kServicePath, &service_vtable, tlsdate_state) == FALSE)
    {
      error ("[dbus] failed to register object path: %s", kServicePath);
      goto err;
    }

  debug ("[dbus] initialized");
  return 0;
err:
  tlsdate_state->dbus = NULL;
  free (state);
  return 1;
}
