import Foundation
import CoreBluetooth

@available(iOS 10.0, *)
@objc(BluetoothPeripheral)
class BluetoothPeripheral: NSObject {
    @objc(subscribeToStateChange)
    func subscribeToStateChange() {
        PeripheralManager.instance.subscribeToStateChanges({ t in
        
        })
    }
    
    @objc(setServiceUUID:)
    func setServiceUUID(_ serviceUUID: String) {
        PeripheralManager.instance.setServiceUUID(serviceUUID)
    }
    
    @objc(setDeviceName:)
    func setDeviceName(_ deviceName: String) {
        PeripheralManager.instance.setDeviceName(deviceName)
    }
    
    @objc func startAdvertising() {
        PeripheralManager.instance.startAdvertising()
    }
    
    @objc(addCharacteristic:characteristicProperties:permissions:)
    func addCharacteristic(_ characteristicUuid: String, characteristicProperties: [String], permissions: [String]) {
        let properties: CBCharacteristicProperties = self.parseCharacteristicProperties(strings: characteristicProperties)
        let permissions: CBAttributePermissions = self.parseCharacteristicPermissions(permissions: permissions)
        let characteristic = CBMutableCharacteristic(type: CBUUID(string: characteristicUuid),
                                                     properties: properties,
                                                     value: nil,
                                                     permissions: permissions)
        PeripheralManager.instance.addCharacteristic(characteristic)
    }
    
    @objc func stopAdvertising() {
        PeripheralManager.instance.stopAdvertising()
    }
    
    @objc static func requiresMainQueueSetup() -> Bool {
        return false
    }
    
    private func parseCharacteristicProperties(strings characteristics: [String]) -> CBCharacteristicProperties {
        var propertySet: CBCharacteristicProperties = []
        
        for characteristic in characteristics {
            switch characteristic {
            case "notify":
                propertySet.insert(.notify)
                continue
            case "writeWithoutResponse":
                propertySet.insert(.writeWithoutResponse)
                continue
            case "write":
                propertySet.insert(.write)
                continue
            default:
                continue
            }
        }
        
        return propertySet
    }
    
    private func parseCharacteristicPermissions(permissions: [String]) -> CBAttributePermissions {
        var attributeSet: CBAttributePermissions = []
        
        for permission in permissions {
            switch permission {
            case "readable":
                attributeSet.insert(.readable)
                break;
            case "readEncryptionRequired":
                attributeSet.insert(.readEncryptionRequired)
                break;
            case "writeable":
                attributeSet.insert(.writeable)
                break;
            case "writeEncryptionRequired":
                attributeSet.insert(.writeEncryptionRequired)
                break;
            default:
                continue
            }
        }
        
        return attributeSet
    }
    
}
