//======== Copyright (c) 2017 Valve Corporation, All rights reserved. =========
//
// Purpose: HID device abstraction temporary stub
//
//=============================================================================
#include "../../SDL_internal.h"

#ifdef SDL_JOYSTICK_HIDAPI

#include <CoreBluetooth/CoreBluetooth.h>
#include <QuartzCore/QuartzCore.h>
#import <UIKit/UIKit.h>
#import <mach/mach_time.h>
#include <pthread.h>
#include <sys/time.h>
#include <unistd.h>
#include "../hidapi/hidapi.h"

#define VALVE_USB_VID       0x28DE
#define D0G_BLE2_PID        0x1106

typedef uint32_t uint32;
typedef uint64_t uint64;

// enables detailed NSLog logging of feature reports
#define FEATURE_REPORT_LOGGING	0

#define REPORT_SEGMENT_DATA_FLAG	0x80
#define REPORT_SEGMENT_LAST_FLAG	0x40

#define VALVE_SERVICE		@"100F6C32-1735-4313-B402-38567131E5F3"

// (READ/NOTIFICATIONS)
#define VALVE_INPUT_CHAR	@"100F6C33-1735-4313-B402-38567131E5F3"

//  (READ/WRITE)
#define VALVE_REPORT_CHAR	@"100F6C34-1735-4313-B402-38567131E5F3"

// TODO: create CBUUID's in __attribute__((constructor)) rather than doing [CBUUID UUIDWithString:...] everywhere

#pragma pack(push,1)

typedef struct
{
	uint8_t		segmentHeader;
	uint8_t		featureReportMessageID;
	uint8_t		length;
	uint8_t		settingIdentifier;
	union {
		uint16_t	usPayload;
		uint32_t	uPayload;
		uint64_t	ulPayload;
		uint8_t		ucPayload[15];
	};
} bluetoothSegment;

typedef struct {
	uint8_t		id;
	union {
		bluetoothSegment segment;
		struct {
			uint8_t		segmentHeader;
			uint8_t		featureReportMessageID;
			uint8_t		length;
			uint8_t		settingIdentifier;
			union {
				uint16_t	usPayload;
				uint32_t	uPayload;
				uint64_t	ulPayload;
				uint8_t		ucPayload[15];
			};
		};
	};
} hidFeatureReport;

#pragma pack(pop)

size_t GetBluetoothSegmentSize(bluetoothSegment *segment)
{
    return segment->length + 3;
}

#define RingBuffer_cbElem   19
#define RingBuffer_nElem    4096

typedef struct {
	int _first, _last;
	uint8_t _data[ ( RingBuffer_nElem * RingBuffer_cbElem ) ];
	pthread_mutex_t accessLock;
} RingBuffer;

static void RingBuffer_init( RingBuffer *this )
{
    this->_first = -1;
    this->_last = 0;
    pthread_mutex_init( &this->accessLock, 0 );
}
	
static bool RingBuffer_write( RingBuffer *this, const uint8_t *src )
{
    pthread_mutex_lock( &this->accessLock );
    memcpy( &this->_data[ this->_last ], src, RingBuffer_cbElem );
    if ( this->_first == -1 )
    {
        this->_first = this->_last;
    }
    this->_last = ( this->_last + RingBuffer_cbElem ) % (RingBuffer_nElem * RingBuffer_cbElem);
    if ( this->_last == this->_first )
    {
        this->_first = ( this->_first + RingBuffer_cbElem ) % (RingBuffer_nElem * RingBuffer_cbElem);
        pthread_mutex_unlock( &this->accessLock );
        return false;
    }
    pthread_mutex_unlock( &this->accessLock );
    return true;
}

static bool RingBuffer_read( RingBuffer *this, uint8_t *dst )
{
    pthread_mutex_lock( &this->accessLock );
    if ( this->_first == -1 )
    {
        pthread_mutex_unlock( &this->accessLock );
        return false;
    }
    memcpy( dst, &this->_data[ this->_first ], RingBuffer_cbElem );
    this->_first = ( this->_first + RingBuffer_cbElem ) % (RingBuffer_nElem * RingBuffer_cbElem);
    if ( this->_first == this->_last )
    {
        this->_first = -1;
    }
    pthread_mutex_unlock( &this->accessLock );
    return true;
}


#pragma mark HIDBLEDevice Definition

typedef enum
{
	BLEDeviceWaitState_None,
	BLEDeviceWaitState_Waiting,
	BLEDeviceWaitState_Complete,
	BLEDeviceWaitState_Error
} BLEDeviceWaitState;

@interface HIDBLEDevice : NSObject <CBPeripheralDelegate>
{
	RingBuffer _inputReports;
	uint8_t	_featureReport[20];
	BLEDeviceWaitState	_waitStateForReadFeatureReport;
	BLEDeviceWaitState	_waitStateForWriteFeatureReport;
}

@property (nonatomic, readwrite) bool connected;
@property (nonatomic, readwrite) bool ready;

@property (nonatomic, strong) CBPeripheral     *bleSteamController;
@property (nonatomic, strong) CBCharacteristic *bleCharacteristicInput;
@property (nonatomic, strong) CBCharacteristic *bleCharacteristicReport;

- (id)initWithPeripheral:(CBPeripheral *)peripheral;

@end


@interface HIDBLEManager : NSObject <CBCentralManagerDelegate>

@property (nonatomic) int nPendingScans;
@property (nonatomic) int nPendingPairs;
@property (nonatomic, strong) CBCentralManager *centralManager;
@property (nonatomic, strong) NSMapTable<CBPeripheral *, HIDBLEDevice *> *deviceMap;
@property (nonatomic, retain) dispatch_queue_t bleSerialQueue;

+ (instancetype)sharedInstance;
- (void)startScan:(int)duration;
- (void)stopScan;
- (int)updateConnectedSteamControllers:(BOOL) bForce;
- (void)appWillResignActiveNotification:(NSNotification *)note;
- (void)appDidBecomeActiveNotification:(NSNotification *)note;

@end


// singleton class - access using HIDBLEManager.sharedInstance
@implementation HIDBLEManager

+ (instancetype)sharedInstance
{
	static HIDBLEManager *sharedInstance = nil;
	static dispatch_once_t onceToken;
	dispatch_once(&onceToken, ^{
		sharedInstance = [HIDBLEManager new];
		sharedInstance.nPendingScans = 0;
		sharedInstance.nPendingPairs = 0;
		
		[[NSNotificationCenter defaultCenter] addObserver:sharedInstance selector:@selector(appWillResignActiveNotification:) name: UIApplicationWillResignActiveNotification object:nil];
		[[NSNotificationCenter defaultCenter] addObserver:sharedInstance selector:@selector(appDidBecomeActiveNotification:) name:UIApplicationDidBecomeActiveNotification object:nil];

		// receive reports on a high-priority serial-queue. optionally put writes on the serial queue to avoid logical
		// race conditions talking to the controller from multiple threads, although BLE fragmentation/assembly means
		// that we can still screw this up.
		// most importantly we need to consume reports at a high priority to avoid the OS thinking we aren't really
		// listening to the BLE device, as iOS on slower devices may stop delivery of packets to the app WITHOUT ACTUALLY
		// DISCONNECTING FROM THE DEVICE if we don't react quickly enough to their delivery.
		// see also the error-handling states in the peripheral delegate to re-open the device if it gets closed
		sharedInstance.bleSerialQueue = dispatch_queue_create( "com.valvesoftware.steamcontroller.ble", DISPATCH_QUEUE_SERIAL );
		dispatch_set_target_queue( sharedInstance.bleSerialQueue, dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_HIGH, 0 ) );

		// creating a CBCentralManager will always trigger a future centralManagerDidUpdateState:
		// where any scanning gets started or connecting to existing peripherals happens, it's never already in a
		// powered-on state for a newly launched application.
		sharedInstance.centralManager = [[CBCentralManager alloc] initWithDelegate:sharedInstance queue:sharedInstance.bleSerialQueue];
		sharedInstance.deviceMap = [[NSMapTable alloc] initWithKeyOptions:NSMapTableWeakMemory valueOptions:NSMapTableStrongMemory capacity:4];
	});
	return sharedInstance;
}

// called for NSNotification UIApplicationWillResignActiveNotification
- (void)appWillResignActiveNotification:(NSNotification *)note
{
	// we'll get resign-active notification if pairing is happening.
	if ( self.nPendingPairs > 0 )
		return;

	for ( CBPeripheral *peripheral in self.deviceMap )
	{
		HIDBLEDevice *steamController = [self.deviceMap objectForKey:peripheral];
		if ( steamController )
		{
			steamController.connected = NO;
			steamController.ready = NO;
			[self.centralManager cancelPeripheralConnection:peripheral];
		}
	}
	[self.deviceMap removeAllObjects];
}

// called for NSNotification UIApplicationDidBecomeActiveNotification
//  whenever the application comes back from being inactive, trigger a 20s pairing scan and reconnect
//  any devices that may have paired while we were inactive.
- (void)appDidBecomeActiveNotification:(NSNotification *)note
{
	[self updateConnectedSteamControllers:true];
	[self startScan:20];
}

- (int)updateConnectedSteamControllers:(BOOL) bForce
{
	static uint64_t s_unLastUpdateTick = 0;
	static mach_timebase_info_data_t s_timebase_info;
	
	if (s_timebase_info.denom == 0)
	{
		mach_timebase_info( &s_timebase_info );
	}
	
	uint64_t ticksNow = mach_approximate_time();
	if ( !bForce && ( ( (ticksNow - s_unLastUpdateTick) * s_timebase_info.numer ) / s_timebase_info.denom ) < (5ull * NSEC_PER_SEC) )
		return (int)self.deviceMap.count;
	
	// we can see previously connected BLE peripherals but can't connect until the CBCentralManager
	// is fully powered up - only do work when we are in that state
	if ( self.centralManager.state != CBManagerStatePoweredOn )
		return (int)self.deviceMap.count;

	// only update our last-check-time if we actually did work, otherwise there can be a long delay during initial power-up
	s_unLastUpdateTick = mach_approximate_time();
	
	// if a pair is in-flight, the central manager may still give it back via retrieveConnected... and
	// cause the SDL layer to attempt to initialize it while some of its endpoints haven't yet been established
	if ( self.nPendingPairs > 0 )
		return (int)self.deviceMap.count;

	NSArray<CBPeripheral *> *peripherals = [self.centralManager retrieveConnectedPeripheralsWithServices: @[ [CBUUID UUIDWithString:@"180A"]]];
	for ( CBPeripheral *peripheral in peripherals )
	{
		// we already know this peripheral
		if ( [self.deviceMap objectForKey: peripheral] != nil )
			continue;
		
		NSLog( @"connected peripheral: %@", peripheral );
		if ( [peripheral.name isEqualToString:@"SteamController"] )
		{
			HIDBLEDevice *steamController = [[HIDBLEDevice alloc] initWithPeripheral:peripheral];
			[self.deviceMap setObject:steamController forKey:peripheral];
			[self.centralManager connectPeripheral:peripheral options:nil];
		}
	}

	return (int)self.deviceMap.count;
}

// manual API for folks to start & stop scanning
- (void)startScan:(int)duration
{
	NSLog( @"BLE: requesting scan for %d seconds", duration );
	@synchronized (self)
	{
		if ( _nPendingScans++ == 0 )
		{
			[self.centralManager scanForPeripheralsWithServices:nil options:nil];
		}
	}

	if ( duration != 0 )
	{
		dispatch_after( dispatch_time( DISPATCH_TIME_NOW, (int64_t)(duration * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
			[self stopScan];
		});
	}
}

- (void)stopScan
{
	NSLog( @"BLE: stopping scan" );
	@synchronized (self)
	{
		if ( --_nPendingScans <= 0 )
		{
			_nPendingScans = 0;
			[self.centralManager stopScan];
		}
	}
}


#pragma mark CBCentralManagerDelegate Implementation

// called whenever the BLE hardware state changes.
- (void)centralManagerDidUpdateState:(CBCentralManager *)central
{
	switch ( central.state )
	{
		case CBCentralManagerStatePoweredOn:
		{
			NSLog( @"CoreBluetooth BLE hardware is powered on and ready" );
			
			// at startup, if we have no already attached peripherals, do a 20s scan for new unpaired devices,
			// otherwise callers should occaisionally do additional scans. we don't want to continuously be
			// scanning because it drains battery, causes other nearby people to have a hard time pairing their
			// Steam Controllers, and may also trigger firmware weirdness when a device attempts to start
			// the pairing sequence multiple times concurrently
			if ( [self updateConnectedSteamControllers:false] == 0 )
			{
				// TODO: we could limit our scan to only peripherals supporting the SteamController service, but
				//  that service doesn't currently fit in the base advertising packet, we'd need to put it into an
				//  extended scan packet. Useful optimization downstream, but not currently necessary
				//	NSArray *services = @[[CBUUID UUIDWithString:VALVE_SERVICE]];
				[self startScan:20];
			}
			break;
		}
			
		case CBCentralManagerStatePoweredOff:
			NSLog( @"CoreBluetooth BLE hardware is powered off" );
			break;
			
		case CBCentralManagerStateUnauthorized:
			NSLog( @"CoreBluetooth BLE state is unauthorized" );
			break;
			
		case CBCentralManagerStateUnknown:
			NSLog( @"CoreBluetooth BLE state is unknown" );
			break;
			
		case CBCentralManagerStateUnsupported:
			NSLog( @"CoreBluetooth BLE hardware is unsupported on this platform" );
			break;
		
		case CBCentralManagerStateResetting:
			NSLog( @"CoreBluetooth BLE manager is resetting" );
			break;
	}
}

- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral
{
	HIDBLEDevice *steamController = [_deviceMap objectForKey:peripheral];
	steamController.connected = YES;
	self.nPendingPairs -= 1;
}

- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error
{
	NSLog( @"Failed to connect: %@", error );
	[_deviceMap removeObjectForKey:peripheral];
	self.nPendingPairs -= 1;
}

- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI
{
	NSString *localName = [advertisementData objectForKey:CBAdvertisementDataLocalNameKey];
	NSString *log = [NSString stringWithFormat:@"Found '%@'", localName];
	
	if ( [localName isEqualToString:@"SteamController"] )
	{
		NSLog( @"%@ : %@ - %@", log, peripheral, advertisementData );
		self.nPendingPairs += 1;
		HIDBLEDevice *steamController = [[HIDBLEDevice alloc] initWithPeripheral:peripheral];
		[self.deviceMap setObject:steamController forKey:peripheral];
		[self.centralManager connectPeripheral:peripheral options:nil];
	}
}

- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error
{
	HIDBLEDevice *steamController = [self.deviceMap objectForKey:peripheral];
	if ( steamController )
	{
		steamController.connected = NO;
		steamController.ready = NO;
		[self.deviceMap removeObjectForKey:peripheral];
	}
}

@end


// Core Bluetooth devices calling back on event boundaries of their run-loops. so annoying.
static void process_pending_events()
{
	CFRunLoopRunResult res;
	do
	{
		res = CFRunLoopRunInMode( kCFRunLoopDefaultMode, 0.001, FALSE );
	}
	while( res != kCFRunLoopRunFinished && res != kCFRunLoopRunTimedOut );
}

@implementation HIDBLEDevice

- (id)init
{
	if ( self = [super init] )
	{
        RingBuffer_init( &_inputReports );
		self.bleSteamController = nil;
		self.bleCharacteristicInput = nil;
		self.bleCharacteristicReport = nil;
		_connected = NO;
		_ready = NO;
	}
	return self;
}

- (id)initWithPeripheral:(CBPeripheral *)peripheral
{
	if ( self = [super init] )
	{
        RingBuffer_init( &_inputReports );
		_connected = NO;
		_ready = NO;
		self.bleSteamController = peripheral;
		if ( peripheral )
		{
			peripheral.delegate = self;
		}
		self.bleCharacteristicInput = nil;
		self.bleCharacteristicReport = nil;
	}
	return self;
}

- (void)setConnected:(bool)connected
{
	_connected = connected;
	if ( _connected )
	{
		[_bleSteamController discoverServices:nil];
	}
	else
	{
		NSLog( @"Disconnected" );
	}
}

- (size_t)read_input_report:(uint8_t *)dst
{
	if ( RingBuffer_read( &_inputReports, dst+1 ) )
	{
		*dst = 0x03;
		return 20;
	}
	return 0;
}

- (int)send_report:(const uint8_t *)data length:(size_t)length
{
	[_bleSteamController writeValue:[NSData dataWithBytes:data length:length] forCharacteristic:_bleCharacteristicReport type:CBCharacteristicWriteWithResponse];
	return (int)length;
}

- (int)send_feature_report:(hidFeatureReport *)report
{
#if FEATURE_REPORT_LOGGING
	uint8_t *reportBytes = (uint8_t *)report;
	
	NSLog( @"HIDBLE:send_feature_report (%02zu/19) [%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x]", GetBluetoothSegmentSize( report->segment ),
		  reportBytes[1], reportBytes[2], reportBytes[3], reportBytes[4], reportBytes[5], reportBytes[6],
		  reportBytes[7], reportBytes[8], reportBytes[9], reportBytes[10], reportBytes[11], reportBytes[12],
		  reportBytes[13], reportBytes[14], reportBytes[15], reportBytes[16], reportBytes[17], reportBytes[18],
		  reportBytes[19] );
#endif

	int sendSize = (int)GetBluetoothSegmentSize( &report->segment );
	if ( sendSize > 20 )
		sendSize = 20;

#if 1
	// fire-and-forget - we are going to not wait for the response here because all Steam Controller BLE send_feature_report's are ignored,
	//  except errors.
	[_bleSteamController writeValue:[NSData dataWithBytes:&report->segment length:sendSize] forCharacteristic:_bleCharacteristicReport type:CBCharacteristicWriteWithResponse];
	
	// pretend we received a result anybody cares about
	return 19;

#else
	// this is technically the correct send_feature_report logic if you want to make sure it gets through and is
	// acknowledged or errors out
	_waitStateForWriteFeatureReport = BLEDeviceWaitState_Waiting;
	[_bleSteamController writeValue:[NSData dataWithBytes:&report->segment length:sendSize
									 ] forCharacteristic:_bleCharacteristicReport type:CBCharacteristicWriteWithResponse];
	
	while ( _waitStateForWriteFeatureReport == BLEDeviceWaitState_Waiting )
	{
		process_pending_events();
	}
	
	if ( _waitStateForWriteFeatureReport == BLEDeviceWaitState_Error )
	{
		_waitStateForWriteFeatureReport = BLEDeviceWaitState_None;
		return -1;
	}
	
	_waitStateForWriteFeatureReport = BLEDeviceWaitState_None;
	return 19;
#endif
}

- (int)get_feature_report:(uint8_t)feature into:(uint8_t *)buffer
{
	_waitStateForReadFeatureReport = BLEDeviceWaitState_Waiting;
	[_bleSteamController readValueForCharacteristic:_bleCharacteristicReport];
	
	while ( _waitStateForReadFeatureReport == BLEDeviceWaitState_Waiting )
		process_pending_events();
	
	if ( _waitStateForReadFeatureReport == BLEDeviceWaitState_Error )
	{
		_waitStateForReadFeatureReport = BLEDeviceWaitState_None;
		return -1;
	}
	
	memcpy( buffer, _featureReport, sizeof(_featureReport) );
	
	_waitStateForReadFeatureReport = BLEDeviceWaitState_None;
	
#if FEATURE_REPORT_LOGGING
	NSLog( @"HIDBLE:get_feature_report (19) [%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x]",
		  buffer[1], buffer[2], buffer[3], buffer[4], buffer[5], buffer[6],
		  buffer[7], buffer[8], buffer[9], buffer[10], buffer[11], buffer[12],
		  buffer[13], buffer[14], buffer[15], buffer[16], buffer[17], buffer[18],
		  buffer[19] );
#endif

	return 19;
}

#pragma mark CBPeripheralDelegate Implementation

- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error
{
	for (CBService *service in peripheral.services)
	{
		NSLog( @"Found Service: %@", service );
		if ( [service.UUID isEqual:[CBUUID UUIDWithString:VALVE_SERVICE]] )
		{
			[peripheral discoverCharacteristics:nil forService:service];
		}
	}
}

- (void)peripheral:(CBPeripheral *)peripheral didDiscoverDescriptorsForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
{
	// nothing yet needed here, enable for logging
	if ( /* DISABLES CODE */ (0) )
	{
		for ( CBDescriptor *descriptor in characteristic.descriptors )
		{
			NSLog( @" - Descriptor '%@'", descriptor );
		}
	}
}

- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error
{
	if ([service.UUID isEqual:[CBUUID UUIDWithString:VALVE_SERVICE]])
	{
		for (CBCharacteristic *aChar in service.characteristics)
		{
			NSLog( @"Found Characteristic %@", aChar );
			
			if ( [aChar.UUID isEqual:[CBUUID UUIDWithString:VALVE_INPUT_CHAR]] )
			{
				self.bleCharacteristicInput = aChar;
			}
			else if ( [aChar.UUID isEqual:[CBUUID UUIDWithString:VALVE_REPORT_CHAR]] )
			{
				self.bleCharacteristicReport = aChar;
				[self.bleSteamController discoverDescriptorsForCharacteristic: aChar];
			}
		}
	}
}

- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
{
	static uint64_t s_ticksLastOverflowReport = 0;

	// receiving an input report is the final indicator that the user accepted a pairing
	// request and that we successfully established notification. CoreBluetooth has no
	// notification of the pairing acknowledgement, which is a bad oversight.
	if ( self.ready == NO )
	{
		self.ready = YES;
		HIDBLEManager.sharedInstance.nPendingPairs -= 1;
	}

	if ( [characteristic.UUID isEqual:_bleCharacteristicInput.UUID] )
	{
		NSData *data = [characteristic value];
		if ( data.length != 19 )
		{
			NSLog( @"HIDBLE: incoming data is %lu bytes should be exactly 19", (unsigned long)data.length );
		}
		if ( !RingBuffer_write( &_inputReports, (const uint8_t *)data.bytes ) )
		{
			uint64_t ticksNow = mach_approximate_time();
			if ( ticksNow - s_ticksLastOverflowReport > (5ull * NSEC_PER_SEC / 10) )
			{
				NSLog( @"HIDBLE: input report buffer overflow" );
				s_ticksLastOverflowReport = ticksNow;
			}
		}
	}
	else if ( [characteristic.UUID isEqual:_bleCharacteristicReport.UUID] )
	{
		memset( _featureReport, 0, sizeof(_featureReport) );
		
		if ( error != nil )
		{
			NSLog( @"HIDBLE: get_feature_report error: %@", error );
			_waitStateForReadFeatureReport = BLEDeviceWaitState_Error;
		}
		else
		{
			NSData *data = [characteristic value];
			if ( data.length != 20 )
			{
				NSLog( @"HIDBLE: incoming data is %lu bytes should be exactly 20", (unsigned long)data.length );
			}
			memcpy( _featureReport, data.bytes, MIN( data.length, sizeof(_featureReport) ) );
			_waitStateForReadFeatureReport = BLEDeviceWaitState_Complete;
		}
	}
}

- (void)peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
{
	if ( [characteristic.UUID isEqual:[CBUUID UUIDWithString:VALVE_REPORT_CHAR]] )
	{
		if ( error != nil )
		{
			NSLog( @"HIDBLE: write_feature_report error: %@", error );
			_waitStateForWriteFeatureReport = BLEDeviceWaitState_Error;
		}
		else
		{
			_waitStateForWriteFeatureReport = BLEDeviceWaitState_Complete;
		}
	}
}

- (void)peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
{
	NSLog( @"didUpdateNotifcationStateForCharacteristic %@ (%@)", characteristic, error );
}

@end


#pragma mark hid_api implementation

struct hid_device_ {
	void *device_handle;
	int blocking;
	hid_device *next;
};

int HID_API_EXPORT HID_API_CALL hid_init(void)
{
	return ( HIDBLEManager.sharedInstance == nil ) ? -1 : 0;
}

int HID_API_EXPORT HID_API_CALL hid_exit(void)
{
	return 0;
}

void HID_API_EXPORT HID_API_CALL hid_ble_scan( bool bStart )
{
	HIDBLEManager *bleManager = HIDBLEManager.sharedInstance;
	if ( bStart )
	{
		[bleManager startScan:0];
	}
	else
	{
		[bleManager stopScan];
	}
}

hid_device * HID_API_EXPORT hid_open_path( const char *path, int bExclusive /* = false */ )
{
	hid_device *result = NULL;
	NSString *nssPath = [NSString stringWithUTF8String:path];
	HIDBLEManager *bleManager = HIDBLEManager.sharedInstance;
	NSEnumerator<HIDBLEDevice *> *devices = [bleManager.deviceMap objectEnumerator];
	
	for ( HIDBLEDevice *device in devices )
	{
		// we have the device but it hasn't found its service or characteristics until it is connected
		if ( !device.ready || !device.connected || !device.bleCharacteristicInput )
			continue;
		
		if ( [device.bleSteamController.identifier.UUIDString isEqualToString:nssPath] )
		{
			result = (hid_device *)malloc( sizeof( hid_device ) );
			memset( result, 0, sizeof( hid_device ) );
			result->device_handle = (void*)CFBridgingRetain( device );
			result->blocking = NO;
			// enable reporting input events on the characteristic
			[device.bleSteamController setNotifyValue:YES forCharacteristic:device.bleCharacteristicInput];
			return result;
		}
	}
	return result;
}

void  HID_API_EXPORT hid_free_enumeration(struct hid_device_info *devs)
{
	/* This function is identical to the Linux version. Platform independent. */
	struct hid_device_info *d = devs;
	while (d) {
		struct hid_device_info *next = d->next;
		free(d->path);
		free(d->serial_number);
		free(d->manufacturer_string);
		free(d->product_string);
		free(d);
		d = next;
	}
}

int HID_API_EXPORT hid_set_nonblocking(hid_device *dev, int nonblock)
{
	/* All Nonblocking operation is handled by the library. */
	dev->blocking = !nonblock;
	
	return 0;
}

struct hid_device_info  HID_API_EXPORT *hid_enumerate(unsigned short vendor_id, unsigned short product_id)
{ @autoreleasepool {
	struct hid_device_info *root = NULL;
	
	if ( ( vendor_id == 0 && product_id == 0 ) ||
		 ( vendor_id == VALVE_USB_VID && product_id == D0G_BLE2_PID ) )
	{
		HIDBLEManager *bleManager = HIDBLEManager.sharedInstance;
		[bleManager updateConnectedSteamControllers:false];
		NSEnumerator<HIDBLEDevice *> *devices = [bleManager.deviceMap objectEnumerator];
		for ( HIDBLEDevice *device in devices )
		{
			// there are several brief windows in connecting to an already paired device and
			// one long window waiting for users to confirm pairing where we don't want
			// to consider a device ready - if we hand it back to SDL or another
			// Steam Controller consumer, their additional SC setup work will fail
			// in unusual/silent ways and we can actually corrupt the BLE stack for
			// the entire system and kill the appletv remote's Menu button (!)
			if ( device.bleSteamController.state != CBPeripheralStateConnected ||
				 device.connected == NO || device.ready == NO )
			{
				if ( device.ready == NO && device.bleCharacteristicInput != nil )
				{
					// attempt to register for input reports. this call will silently fail
					// until the pairing finalizes with user acceptance. oh, apple.
					[device.bleSteamController setNotifyValue:YES forCharacteristic:device.bleCharacteristicInput];
				}
				continue;
			}
			struct hid_device_info *device_info = (struct hid_device_info *)malloc( sizeof(struct hid_device_info) );
			memset( device_info, 0, sizeof(struct hid_device_info) );
			device_info->next = root;
			root = device_info;
			device_info->path = strdup( device.bleSteamController.identifier.UUIDString.UTF8String );
			device_info->vendor_id = VALVE_USB_VID;
			device_info->product_id = D0G_BLE2_PID;
			device_info->product_string = wcsdup( L"Steam Controller" );
			device_info->manufacturer_string = wcsdup( L"Valve Corporation" );
		}
	}
	return root;
}}

int HID_API_EXPORT_CALL hid_get_manufacturer_string(hid_device *dev, wchar_t *string, size_t maxlen)
{
	static wchar_t s_wszManufacturer[] = L"Valve Corporation";
	wcsncpy( string, s_wszManufacturer, sizeof(s_wszManufacturer)/sizeof(s_wszManufacturer[0]) );
	return 0;
}

int HID_API_EXPORT_CALL hid_get_product_string(hid_device *dev, wchar_t *string, size_t maxlen)
{
	static wchar_t s_wszProduct[] = L"Steam Controller";
	wcsncpy( string, s_wszProduct, sizeof(s_wszProduct)/sizeof(s_wszProduct[0]) );
	return 0;
}

int HID_API_EXPORT_CALL hid_get_serial_number_string(hid_device *dev, wchar_t *string, size_t maxlen)
{
	static wchar_t s_wszSerial[] = L"12345";
	wcsncpy( string, s_wszSerial, sizeof(s_wszSerial)/sizeof(s_wszSerial[0]) );
	return 0;
}

int HID_API_EXPORT hid_write(hid_device *dev, const unsigned char *data, size_t length)
{
    HIDBLEDevice *device_handle = (__bridge HIDBLEDevice *)dev->device_handle;

	if ( !device_handle.connected )
		return -1;

	return [device_handle send_report:data length:length];
}

void HID_API_EXPORT hid_close(hid_device *dev)
{
    HIDBLEDevice *device_handle = CFBridgingRelease( dev->device_handle );

	// disable reporting input events on the characteristic
	if ( device_handle.connected ) {
		[device_handle.bleSteamController setNotifyValue:NO forCharacteristic:device_handle.bleCharacteristicInput];
	}

	free( dev );
}

int HID_API_EXPORT hid_send_feature_report(hid_device *dev, const unsigned char *data, size_t length)
{
    HIDBLEDevice *device_handle = (__bridge HIDBLEDevice *)dev->device_handle;

	if ( !device_handle.connected )
		return -1;

	return [device_handle send_feature_report:(hidFeatureReport *)(void *)data];
}

int HID_API_EXPORT hid_get_feature_report(hid_device *dev, unsigned char *data, size_t length)
{
    HIDBLEDevice *device_handle = (__bridge HIDBLEDevice *)dev->device_handle;

	if ( !device_handle.connected )
		return -1;

	size_t written = [device_handle get_feature_report:data[0] into:data];
	
	return written == length-1 ? (int)length : (int)written;
}

int HID_API_EXPORT hid_read(hid_device *dev, unsigned char *data, size_t length)
{
    HIDBLEDevice *device_handle = (__bridge HIDBLEDevice *)dev->device_handle;

	if ( !device_handle.connected )
		return -1;

	return hid_read_timeout(dev, data, length, 0);
}

int HID_API_EXPORT hid_read_timeout(hid_device *dev, unsigned char *data, size_t length, int milliseconds)
{
    HIDBLEDevice *device_handle = (__bridge HIDBLEDevice *)dev->device_handle;

	if ( !device_handle.connected )
		return -1;
	
	if ( milliseconds != 0 )
	{
		NSLog( @"hid_read_timeout with non-zero wait" );
	}
	int result = (int)[device_handle read_input_report:data];
#if FEATURE_REPORT_LOGGING
	NSLog( @"HIDBLE:hid_read_timeout (%d) [%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x]", result,
		  data[1], data[2], data[3], data[4], data[5], data[6],
		  data[7], data[8], data[9], data[10], data[11], data[12],
		  data[13], data[14], data[15], data[16], data[17], data[18],
		  data[19] );
#endif
	return result;
}

#endif /* SDL_JOYSTICK_HIDAPI */
