#!/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" : ["PHOTO"] })
		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()
