#include <ble/BleUUID.h>
#include <ble/CHIPBleServiceData.h>
#include <lib/support/CHIPMem.h>
#include <lib/support/logging/CHIPLogging.h>
#include <platform/Darwin/UUIDHelper.h>

#import <CoreBluetooth/CoreBluetooth.h>

namespace {
struct PyObject;
using DeviceScannedCallback
    = void (*)(PyObject * context, const char * address, uint16_t discriminator, uint16_t vendorId, uint16_t productId);
using ScanCompleteCallback = void (*)(PyObject * context);
}

@interface ChipDeviceBleScanner : NSObject <CBCentralManagerDelegate>

@property (strong, nonatomic) dispatch_queue_t workQueue;
@property (nonatomic, readonly, nullable) dispatch_source_t timer;
@property (strong, nonatomic) CBCentralManager * centralManager;
@property (strong, nonatomic) CBUUID * shortServiceUUID;

@property (assign, nonatomic) PyObject * context;
@property (assign, nonatomic) DeviceScannedCallback scanCallback;
@property (assign, nonatomic) ScanCompleteCallback completeCallback;

- (id)initWithContext:(PyObject *)context
         scanCallback:(DeviceScannedCallback)scanCallback
     completeCallback:(ScanCompleteCallback)completeCallback
            timeoutMs:(uint32_t)timeout;

- (void)stopTimeoutReached;

@end

@implementation ChipDeviceBleScanner

- (id)initWithContext:(PyObject *)context
         scanCallback:(DeviceScannedCallback)scanCallback
     completeCallback:(ScanCompleteCallback)completeCallback
            timeoutMs:(uint32_t)timeout
{
    self = [super init];
    if (self) {
        self.shortServiceUUID = [UUIDHelper GetShortestServiceUUID:&chip::Ble::CHIP_BLE_SVC_ID];

        _workQueue = dispatch_queue_create("com.chip.python.ble.work_queue", DISPATCH_QUEUE_SERIAL);
        _timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, _workQueue);
        _centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:_workQueue];
        _context = context;
        _scanCallback = scanCallback;
        _completeCallback = completeCallback;

        dispatch_source_set_event_handler(_timer, ^{
            [self stopTimeoutReached];
        });
        dispatch_source_set_timer(
            _timer, dispatch_walltime(nullptr, timeout * NSEC_PER_MSEC), DISPATCH_TIME_FOREVER, 50 * NSEC_PER_MSEC);
        dispatch_resume(_timer);
    }
    return self;
}

- (void)centralManager:(CBCentralManager *)central
    didDiscoverPeripheral:(CBPeripheral *)peripheral
        advertisementData:(NSDictionary *)advertisementData
                     RSSI:(NSNumber *)RSSI
{
    NSNumber * isConnectable = [advertisementData objectForKey:CBAdvertisementDataIsConnectable];

    if (![isConnectable boolValue]) {
        return;
    }

    NSDictionary * servicesData = [advertisementData objectForKey:CBAdvertisementDataServiceDataKey];
    for (CBUUID * serviceUUID in servicesData) {
        if (![serviceUUID.data isEqualToData:_shortServiceUUID.data]) {
            continue;
        }
        NSData * serviceData = [servicesData objectForKey:serviceUUID];

        NSUInteger length = [serviceData length];
        if (length != sizeof(chip::Ble::ChipBLEDeviceIdentificationInfo)) {
            ChipLogError(Ble, "Device has invalid advertisement data length.");
            break;
        }

        chip::Ble::ChipBLEDeviceIdentificationInfo data;
        memcpy(&data, [serviceData bytes], sizeof(data));

        _scanCallback(_context, [peripheral.identifier.UUIDString UTF8String], data.GetDeviceDiscriminator(), data.GetVendorId(),
            data.GetProductId());

        break;
    }
}

- (void)stopTimeoutReached
{
    ChipLogProgress(Ble, "Scan timeout reached.");

    _completeCallback(_context);

    dispatch_source_cancel(_timer);
    [self.centralManager stopScan];
    self.centralManager = nil;
}

- (void)centralManagerDidUpdateState:(CBCentralManager *)central
{
    switch (central.state) {
    case CBManagerStatePoweredOn:
        ChipLogProgress(Ble, "Central BLE Manager is on. Starting to scan.");
        [central scanForPeripheralsWithServices:@[ _shortServiceUUID ] options:nil];
        break;
    default:
        ChipLogError(Ble, "CBManagerState is NOT ON. Unable to scan.");
        break;
    }
}

- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral
{
}

@end

extern "C" void * pychip_ble_start_scanning(
    PyObject * context, void * adapter, uint32_t timeout, DeviceScannedCallback scanCallback, ScanCompleteCallback completeCallback)
{
    // NOTE: adapter is ignored as it does not apply to mac

    ChipDeviceBleScanner * scanner = [[ChipDeviceBleScanner alloc] initWithContext:context
                                                                      scanCallback:scanCallback
                                                                  completeCallback:completeCallback
                                                                         timeoutMs:timeout];

    return (__bridge_retained void *) (scanner);
}
