#!/usr/bin/python

from __future__ import absolute_import, print_function, unicode_literals

import sys
import dbus
import time
from optparse import OptionParser, make_option
import bluezutils

bus = dbus.SystemBus()

option_list = [
		make_option("-i", "--device", action="store",
				type="string", dest="dev_id"),
		]
parser = OptionParser(option_list=option_list)

(options, args) = parser.parse_args()

adapter_path = bluezutils.find_adapter(options.dev_id).object_path
adapter = dbus.Interface(bus.get_object("org.bluez", adapter_path),
					"org.freedesktop.DBus.Properties")

if (len(args) < 1):
	print("Usage: %s <command>" % (sys.argv[0]))
	print("")
	print("  address")
	print("  list")
	print("  name [name]")
	print("  powered [on/off]")
	print("  pairable [on/off]")
	print("  pairabletimeout [timeout]")
	print("  discoverable [on/off]")
	print("  discoverabletimeout [timeout]")
	print("  discovering")
	sys.exit(1)

if (args[0] == "address"):
	addr = adapter.Get("org.bluez.Adapter1", "Address")
	print(addr)
	sys.exit(0)

if (args[0] == "name"):
	if (len(args) < 2):
		name = adapter.Get("org.bluez.Adapter1", "Name")
		print(name)
	else:
		adapter.Set("org.bluez.Adapter1", "Name", args[1])
	sys.exit(0)

if (args[0] == "list"):
	if (len(args) < 2):
		om = dbus.Interface(bus.get_object("org.bluez", "/"),
					"org.freedesktop.DBus.ObjectManager")
		objects = om.GetManagedObjects()
		for path, interfaces in objects.iteritems():
			if "org.bluez.Adapter1" not in interfaces:
				continue

			print(" [ %s ]" % (path))

			props = interfaces["org.bluez.Adapter1"]

			for (key, value) in props.items():
				if (key == "Class"):
					print("    %s = 0x%06x" % (key, value))
				else:
					print("    %s = %s" % (key, value))
			print()
	sys.exit(0)

if (args[0] == "powered"):
	if (len(args) < 2):
		powered = adapter.Get("org.bluez.Adapter1", "Powered")
		print(powered)
	else:
		if (args[1] == "on"):
			value = dbus.Boolean(1)
		elif (args[1] == "off"):
			value = dbus.Boolean(0)
		else:
			value = dbus.Boolean(args[1])
		adapter.Set("org.bluez.Adapter1", "Powered", value)
	sys.exit(0)

if (args[0] == "pairable"):
	if (len(args) < 2):
		pairable = adapter.Get("org.bluez.Adapter1", "Pairable")
		print(pairable)
	else:
		if (args[1] == "on"):
			value = dbus.Boolean(1)
		elif (args[1] == "off"):
			value = dbus.Boolean(0)
		else:
			value = dbus.Boolean(args[1])
		adapter.Set("org.bluez.Adapter1", "Pairable", value)
	sys.exit(0)

if (args[0] == "pairabletimeout"):
	if (len(args) < 2):
		pt = adapter.Get("org.bluez.Adapter1", "PairableTimeout")
		print(pt)
	else:
		timeout = dbus.UInt32(args[1])
		adapter.Set("org.bluez.Adapter1", "PairableTimeout", timeout)
	sys.exit(0)

if (args[0] == "discoverable"):
	if (len(args) < 2):
		discoverable = adapter.Get("org.bluez.Adapter1", "Discoverable")
		print(discoverable)
	else:
		if (args[1] == "on"):
			value = dbus.Boolean(1)
		elif (args[1] == "off"):
			value = dbus.Boolean(0)
		else:
			value = dbus.Boolean(args[1])
		adapter.Set("org.bluez.Adapter1", "Discoverable", value)
	sys.exit(0)

if (args[0] == "discoverabletimeout"):
	if (len(args) < 2):
		dt = adapter.Get("org.bluez.Adapter1", "DiscoverableTimeout")
		print(dt)
	else:
		to = dbus.UInt32(args[1])
		adapter.Set("org.bluez.Adapter1", "DiscoverableTimeout", to)
	sys.exit(0)

if (args[0] == "discovering"):
	discovering = adapter.Get("org.bluez.Adapter1", "Discovering")
	print(discovering)
	sys.exit(0)

print("Unknown command")
sys.exit(1)
