#!/usr/bin/env python
# -*- coding: utf-8 -*-

import dbus
from sys import argv

# define some nice dbus helper, which I really like, cause make code easier to read :)
def getDbusObject (bus, busname , objectpath , interface):
        dbusObject = bus.get_object(busname, objectpath)
        return dbus.Interface(dbusObject, dbus_interface=interface)

def check_args(data):
  if len(data)>0 and len(data)%2==0:
    pass
  else:
    raise IndexError

def prepare_dict(data):
  dict = {}
  args = data
  while len(args)>0:
    if args[0] == '_limit':
      dict[args[0]]=int(args[1])
    else:
      if dict.has_key(args[0]):
          if type(dict[args[0]])==list:
              dict[args[0]].append(args[1])
          else:
              dict[args[0]]=[dict[args[0]], args[1]]
      else:
          dict[args[0]]=args[1]
    args = args[2:]
  return dict

def query(data):
  if len(data)==0:
    dict = {}
  else:
    check_args(data)
    dict = prepare_dict(data)

  print "Querying data matching to " + str(dict) + "..."
  x = interface.Query(dict)

  print "Query: " + x
  query = getDbusObject (bus, "org.freesmartphone.opimd", x, "org.freesmartphone.PIM."+domain+"Query")
  results = query.GetResultCount()
  print "Number of results: " + str(results)
  for i in range(0,results):
    print "Result nr "+str(i+1)+":"
    result = query.GetResult()
    for field in result:
      if type(result[field]) == dbus.Array:
          for value in result[field]:
              print "  "+field+": "+str(value)
      else:
          value = result[field]
          if isinstance(value, basestring):
              value = value.encode('utf-8')
          else:
              value = str(value)
          print ("  "+field+": ").encode('utf-8') + value
  query.Dispose() # delete query result from memory

def add(data):
  check_args(data)
  dict = prepare_dict(data)
  print "Adding item " + str(dict) + "..."
  interface.Add(dict)
  query(data)

def addincoming(data):
  check_args(data)
  dict = prepare_dict(data)
  print "Adding incoming item " + str(dict) + "..."
  interface.AddIncoming(dict)
  query(data)


def edit(id, data):
  check_args(data)
  dict = prepare_dict(data)
  print "Editing item " + str(id) + " using data: " + str(dict) + "..."
  item_interface = getDbusObject ( bus, "org.freesmartphone.opimd", "/org/freesmartphone/PIM/"+domain+"s/"+id, "org.freesmartphone.PIM."+domain)
  item_interface.Update(dict)
  query(data)

def delete(id):
  print "Deleting item " + str(id) + "..."
  item_interface = getDbusObject ( bus, "org.freesmartphone.opimd", "/org/freesmartphone/PIM/"+domain+"s/"+id, "org.freesmartphone.PIM."+domain)
  item_interface.Delete()

print "------- opimd test app -------"
print " by Sebastian dos Krzyszkowiak"
print "           seba.dos1@gmail.com"
print "------------------------------"

if len(argv)==1 or argv[1]=='--help' or argv[1]=='-h':
  print "Usage: "+argv[0]+" domain job [args]"
  print ""
  print "domain: can be c (or contacts), m (or messages), ca (or calls), d (or dates), n (or notes) and t (or tasks). Defines what domain " + argv[0] + " will use."
  print "job: can be query, add, edit or delete."
  print "args: depending of job:"
  print "      query:  every pair of arguments is combined to fields (name, value)"
  print "              for instance: "+argv[0]+" contacts query Name dos"
  print "      add:    every pair of arguments is combined to fields (name, value)"
  print "              for instance: "+argv[0]+" contacts add Name dos"
  print "      edit:   first argument from args is ID of edited item, next are pairs of arguments combined to fields (name, value)"
  print "              for instance: "+argv[0]+" contacts edit 0 Name dos1"
  print "      delete: argument is ID of deleted item"
  print "              for instance: "+argv[0]+" contacts delete 0"
  exit(0)

bus = dbus.SystemBus()

try:
  if argv[1].lower()=='contacts' or argv[1].lower()=='c':
    domain = 'Contact'
  elif argv[1].lower()=='messages' or argv[1].lower()=='m':
    domain = 'Message'
  elif argv[1].lower()=='calls' or argv[1].lower()=='ca':
    domain = 'Call'
  elif argv[1].lower()=='dates' or argv[1].lower()=='d':
    domain = 'Date'
  elif argv[1].lower()=='notes' or argv[1].lower()=='n':
    domain = 'Note'
  elif argv[1].lower()=='tasks' or argv[1].lower()=='t':
    domain = 'Task'
  else:
    raise IndexError

  print "Using domain: " + domain + "s"

  interface = getDbusObject (bus, "org.freesmartphone.opimd", "/org/freesmartphone/PIM/"+domain+"s", "org.freesmartphone.PIM."+domain+"s")

  if argv[2].lower()=='query':
    query(argv[3:])
  elif argv[2].lower()=='add':
    add(argv[3:])
  elif argv[2].lower()=='addincoming':
    addincoming(argv[3:])  
  elif argv[2].lower()=='edit':
    edit(argv[3], argv[4:])
  elif argv[2].lower()=='delete':
    delete(argv[3])
  else:
    raise IndexError

  print "Done."
except IndexError:
  print "Incorect arguments. Read --help. Aborting."
  exit(1)
