#include <dbus/dbus.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

/* Unclean Remote for MCabber */

DBusError err;
DBusConnection *conn = NULL;

/* public */

/**
 *
 * @short  Gets a connection to the DBus Session Bus
 *
 * @return The handle for the connection to the bus.
 *
 */

DBusConnection *getConnection();

/**
 *
 * @short  Calls a method over DBus
 *
 */

void callMethod();

/* Definitions */

DBusConnection *getConnection() {

  dbus_error_init(&err);

  conn = dbus_bus_get(DBUS_BUS_SESSION, &err);

  if(conn == NULL) {
    fprintf(stderr, "Connection to session bus failed!\n");
  }
  if (dbus_error_is_set(&err)) { 
    fprintf(stderr, "Error connection to DBus Session Bus: %s\n", err.message); 
    dbus_error_free(&err); 
  }
  return conn;

}

void callMethod(char *param) {

  DBusMessage *msg;
  DBusMessageIter args;
  DBusPendingCall *pending;

  short int a;

  msg = dbus_message_new_method_call("org.freedesktop.mcabber", "/org/freedesktop/mcabber", "org.freedesktop.mcabber", "process_command");

  /* Unclean code - will not check for NULL msg etc */

  dbus_message_iter_init_append(msg, &args);
  if(param[strlen(param) - 1] == '\n')
    param[strlen(param) - 1] = '\0';
  dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &param);
  free(param);

  dbus_connection_send_with_reply (conn, msg, &pending, -1);
  dbus_connection_flush(conn);

  dbus_pending_call_block(pending);
  msg = dbus_pending_call_steal_reply(pending);
  dbus_pending_call_unref(pending);

  dbus_message_iter_init(msg, &args);
  dbus_message_iter_get_basic(&args, &a);

  printf("RPC Returned %d\n", a);

}


int main(int argc, char *argv[]) {

  int i;
  unsigned len;
  char *cmd;
  char *j;

  if(argc == 1) {
    fprintf(stderr, "USAGE: %s <MCabber Command>\n", argv[0]);
    return 1;
  }

  if(argc < 1) {
    // Weird!?
    fprintf(stderr, "USAGE mcabber-remote <MCabber Command>\n");
      return 1;
  }

  len = 0;
  for(i = 1; i < argc; ++i) {
    len += strlen(argv[i]) + 1;
  }

  cmd = (char *)malloc(sizeof(char) * len);
  if(cmd == NULL) {
    fprintf(stderr, "Error: Could not allocate memory for command string!\n");
  }

  j = cmd;

  for(i = 1; i < argc; ++i, j++) {
    strcpy(j, argv[i]);
    j += strlen(argv[i]);
    if(i + 1 < argc)
      *j = ' ';
  }

  fprintf(stderr, "Command: %s\n", cmd);
  
  getConnection();
  callMethod(cmd);

}
