//
//  BluetoothRadio.swift
//  USB Meter
//
//  Created by Bogdan Timofte on 19/03/2020.
//  Copyright © 2020 Bogdan Timofte. All rights reserved.
//

import CoreBluetooth

/**
 Bluetooth Radio Modules
 # DX-BT18 (HM-10)
 - Documentation [DX-BT18 User Manual](https:fccid.io/2AKS8DX-BT18/User-Manual/Users-Manual-4216091)
 - Code [HM10 Bluetooth Serial iOS](https://github.com/hoiberg/HM10-BluetoothSerial-iOS)
 # PW0316
 - Documentation [PW0316 BLE4.0 User Manual](http://www.phangwei.com/o/PW0316_User_Manual_V2.9.pdf)
 # BT24-M
 - Seen in newer TC66C units as a transparent BLE serial module on `FFE0`
 */
enum BluetoothRadio : CaseIterable {
    case BT18
    case PW0316
    case BT24M
    case UNKNOWN
}

/**
 Dictionary containing services used in our communication for each radio
 */
var BluetoothRadioServicesUUIDS: [BluetoothRadio:[CBUUID]] = [
    .BT18 : [CBUUID(string: "FFE0")],
    .PW0316 : [CBUUID(string: "FFE0"), CBUUID(string: "FFE5")],
    .BT24M : [CBUUID(string: "FFE0")]
]

/**
 Dictionary containing preferred notification characteristics used in our communication.

 Notes:
 - UM-family radios are documented around an HM-10 style `FFE0` / `FFE1` path
 - DX-BT18 can additionally expose `FFE2` as a write-only characteristic
 - TC66C PW0316 uses `FFE4` for notifications
 */
var BluetoothRadioNotifyUUIDs: [BluetoothRadio:[CBUUID]] = [
    .BT18 : [CBUUID(string: "FFE1")],
    .PW0316 : [CBUUID(string: "FFE4")],
    .BT24M : [CBUUID(string: "FFE1")]
]

/**
 Dictionary containing preferred write characteristics used in our communication.

 Preference order matters:
 - for BT18 radios we prefer `FFE2` when available and fall back to `FFE1`
 - for PW0316 radios we write to `FFE9`
 */
var BluetoothRadioWriteUUIDs: [BluetoothRadio:[CBUUID]] = [
    .BT18 : [CBUUID(string: "FFE2"), CBUUID(string: "FFE1")],
    .PW0316 : [CBUUID(string: "FFE9")],
    .BT24M : [CBUUID(string: "FFE1")]
]

/**
 Returns an array containing all service UUIDs used by radios
 */
func allBluetoothRadioServices () -> [CBUUID] {
    var retval: [CBUUID] = []
    for radio in BluetoothRadio.allCases {
        for serviceUUID in BluetoothRadioServicesUUIDS[radio] ?? [] {
            if !retval.contains(serviceUUID) {
                retval.append(serviceUUID)
            }
        }
    }
    return retval
}
