#!/usr/bin/python

from __future__ import absolute_import, print_function, unicode_literals

import sys
import dbus
import dbus.service
import dbus.mainloop.glib
import gobject
import bluezutils

A2DP_SOURCE_UUID = "0000110A-0000-1000-8000-00805F9B34FB"
A2DP_SINK_UUID = "0000110B-0000-1000-8000-00805F9B34FB"
HFP_AG_UUID = "0000111F-0000-1000-8000-00805F9B34FB"
HFP_HF_UUID = "0000111E-0000-1000-8000-00805F9B34FB"
HSP_AG_UUID = "00001112-0000-1000-8000-00805F9B34FB"

SBC_CODEC = dbus.Byte(0x00)
#Channel Modes: Mono DualChannel Stereo JointStereo
#Frequencies: 16Khz 32Khz 44.1Khz 48Khz
#Subbands: 4 8
#Blocks: 4 8 12 16
#Bitpool Range: 2-64
SBC_CAPABILITIES = dbus.Array([dbus.Byte(0xff), dbus.Byte(0xff), dbus.Byte(2), dbus.Byte(64)])
# JointStereo 44.1Khz Subbands: Blocks: 16 Bitpool Range: 2-32
SBC_CONFIGURATION = dbus.Array([dbus.Byte(0x21), dbus.Byte(0x15), dbus.Byte(2), dbus.Byte(32)])

MP3_CODEC = dbus.Byte(0x01)
#Channel Modes: Mono DualChannel Stereo JointStereo
#Frequencies: 32Khz 44.1Khz 48Khz
#CRC: YES
#Layer: 3
#Bit Rate: All except Free format
#VBR: Yes
#Payload Format: RFC-2250
MP3_CAPABILITIES = dbus.Array([dbus.Byte(0x3f), dbus.Byte(0x07), dbus.Byte(0xff), dbus.Byte(0xfe)])
# JointStereo 44.1Khz Layer: 3 Bit Rate: VBR Format: RFC-2250
MP3_CONFIGURATION = dbus.Array([dbus.Byte(0x21), dbus.Byte(0x02), dbus.Byte(0x00), dbus.Byte(0x80)])

PCM_CODEC = dbus.Byte(0x00)
PCM_CONFIGURATION = dbus.Array([], signature="ay")

CVSD_CODEC = dbus.Byte(0x01)

class Rejected(dbus.DBusException):
	_dbus_error_name = "org.bluez.Error.Rejected"

class Endpoint(dbus.service.Object):
	exit_on_release = True
	configuration = SBC_CONFIGURATION

	def set_exit_on_release(self, exit_on_release):
		self.exit_on_release = exit_on_release

	def default_configuration(self, configuration):
		self.configuration = configuration

	@dbus.service.method("org.bluez.MediaEndpoint1",
					in_signature="", out_signature="")
	def Release(self):
		print("Release")
		if self.exit_on_release:
			mainloop.quit()

	@dbus.service.method("org.bluez.MediaEndpoint1",
					in_signature="", out_signature="")
	def ClearConfiguration(self):
		print("ClearConfiguration")

	@dbus.service.method("org.bluez.MediaEndpoint1",
					in_signature="oay", out_signature="")
	def SetConfiguration(self, transport, config):
		print("SetConfiguration (%s, %s)" % (transport, config))
		return

	@dbus.service.method("org.bluez.MediaEndpoint1",
					in_signature="ay", out_signature="ay")
	def SelectConfiguration(self, caps):
		print("SelectConfiguration (%s)" % (caps))
		return self.configuration

if __name__ == '__main__':
	dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)

	bus = dbus.SystemBus()

	if len(sys.argv) > 1:
		path = bluezutils.find_adapter(sys.argv[1]).object_path
	else:
		path = bluezutils.find_adapter().object_path

	media = dbus.Interface(bus.get_object("org.bluez", path),
						"org.bluez.Media1")

	path = "/test/endpoint"
	endpoint = Endpoint(bus, path)
	mainloop = gobject.MainLoop()

	properties = dbus.Dictionary({ "UUID" : A2DP_SOURCE_UUID,
					"Codec" : SBC_CODEC,
					"DelayReporting" : True,
					"Capabilities" : SBC_CAPABILITIES })

	if len(sys.argv) > 2:
		if sys.argv[2] == "sbcsink":
			properties = dbus.Dictionary({ "UUID" : A2DP_SINK_UUID,
							"Codec" : SBC_CODEC,
							"DelayReporting" : True,
							"Capabilities" : SBC_CAPABILITIES })
		if sys.argv[2] == "mp3source":
			properties = dbus.Dictionary({ "UUID" : A2DP_SOURCE_UUID,
							"Codec" : MP3_CODEC,
							"Capabilities" : MP3_CAPABILITIES })
			endpoint.default_configuration(MP3_CONFIGURATION)
		if sys.argv[2] == "mp3sink":
			properties = dbus.Dictionary({ "UUID" : A2DP_SINK_UUID,
							"Codec" : MP3_CODEC,
							"Capabilities" : MP3_CAPABILITIES })
			endpoint.default_configuration(MP3_CONFIGURATION)
		if sys.argv[2] == "hfpag" or sys.argv[2] == "hspag":
			properties = dbus.Dictionary({ "UUID" : HFP_AG_UUID,
							"Codec" : PCM_CODEC,
							"Capabilities" :  PCM_CONFIGURATION })
			endpoint.default_configuration(dbus.Array([]))
		if sys.argv[2] == "hfphf":
			properties = dbus.Dictionary({ "UUID" : HFP_HF_UUID,
							"Codec" : CVSD_CODEC,
							"Capabilities" :  PCM_CONFIGURATION })
			endpoint.default_configuration(dbus.Array([]))

	print(properties)

	media.RegisterEndpoint(path, properties)

	mainloop.run()
