#!/usr/bin/python

from __future__ import absolute_import, print_function, unicode_literals

import gobject

import sys
import os
import dbus
import dbus.service
import dbus.mainloop.glib

BUS_NAME='org.bluez.obex'
PATH = '/org/bluez/obex'
CLIENT_INTERFACE = 'org.bluez.obex.Client1'
SESSION_INTERFACE = 'org.bluez.obex.Session1'
PHONEBOOK_ACCESS_INTERFACE = 'org.bluez.obex.PhonebookAccess1'
TRANSFER_INTERFACE = 'org.bluez.obex.Transfer1'

class Transfer:
	def __init__(self, callback_func):
		self.callback_func = callback_func
		self.path = None
		self.filename = None

class PbapClient:
	def __init__(self, session_path):
		self.transfers = 0
		self.props = dict()
		self.flush_func = None
		bus = dbus.SessionBus()
		obj = bus.get_object(BUS_NAME, session_path)
		self.session = dbus.Interface(obj, SESSION_INTERFACE)
		self.pbap = dbus.Interface(obj, PHONEBOOK_ACCESS_INTERFACE)
		bus.add_signal_receiver(self.properties_changed,
			dbus_interface="org.freedesktop.DBus.Properties",
			signal_name="PropertiesChanged",
			path_keyword="path")

	def register(self, path, properties, transfer):
		transfer.path = path
		transfer.filename = properties["Filename"]
		self.props[path] = transfer
		print("Transfer created: %s (file %s)" % (path,
							transfer.filename))

	def error(self, err):
		print(err)
		mainloop.quit()

	def transfer_complete(self, path):
		req = self.props.get(path)
		if req == None:
			return
		self.transfers -= 1
		print "Transfer %s complete" % path
		try:
			f = open(req.filename, "r")
			os.remove(req.filename)
			lines = f.readlines()
			del self.props[path]
			req.callback_func(lines)
		except:
			pass

		if (len(self.props) == 0) and (self.transfers == 0):
			if self.flush_func != None:
				f = self.flush_func
				self.flush_func = None
				f()

	def transfer_error(self, path):
		print("Transfer %s error" % path)
		mainloop.quit()

	def properties_changed(self, interface, properties, invalidated, path):
		req = self.props.get(path)
		if req == None:
			return

		if properties['Status'] == 'complete':
			self.transfer_complete(path)
			return

		if properties['Status'] == 'error':
			self.transfer_error(path)
			return

	def pull(self, vcard, params, func):
		req = Transfer(func)
		self.pbap.Pull(vcard, "", params,
			reply_handler=lambda o, p: self.register(o, p, req),
			error_handler=self.error)
		self.transfers += 1

	def pull_all(self, params, func):
		req = Transfer(func)
		self.pbap.PullAll("", params,
			reply_handler=lambda o, p: self.register(o, p, req),
			error_handler=self.error)
		self.transfers += 1

	def flush_transfers(self, func):
		if (len(self.props) == 0) and (self.transfers == 0):
			return
		self.flush_func = func

	def interface(self):
		return self.pbap

if  __name__ == '__main__':

	dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)

	bus = dbus.SessionBus()
	mainloop = gobject.MainLoop()

	client = dbus.Interface(bus.get_object(BUS_NAME, PATH),
							CLIENT_INTERFACE)

	if (len(sys.argv) < 2):
		print("Usage: %s <device>" % (sys.argv[0]))
		sys.exit(1)

	print "Creating Session"
	session_path = client.CreateSession(sys.argv[1], { "Target": "PBAP" })

	pbap_client = PbapClient(session_path)

	def process_result(lines, header):
		if header != None:
			print(header)
		for line in lines:
			print(line),
		print

	def test_paths(paths):
		if len(paths) == 0:
			print
			print "FINISHED"
			mainloop.quit()
			return

		path = paths[0]

		print "\n--- Select Phonebook %s ---\n" % (path)
		pbap_client.interface().Select("int", path)

		print "\n--- GetSize ---\n"
		ret = pbap_client.interface().GetSize()
		print "Size = %d\n" % (ret)

		print "\n--- List vCard ---\n"
		try:
			ret = pbap_client.interface().List(dbus.Dictionary())
		except:
			ret = []

		params = dbus.Dictionary({ "Format" : "vcard30",
					"Fields" : [ "VERSION", "FN", "TEL"] })
		for item in ret:
			print "%s : %s" % (item[0], item[1])
			pbap_client.pull(item[0], params,
					lambda x: process_result(x, None))

		pbap_client.pull_all(params, lambda x: process_result(x,
							"\n--- PullAll ---\n"))

		pbap_client.flush_transfers(lambda: test_paths(paths[1:]))

	test_paths(["PB", "ICH", "OCH", "MCH", "CCH"])

	mainloop.run()
