/*
 *  Copyright © 2016, 2017, Oracle and/or its affiliates. All rights reserved.
 *  This software is dual-licensed to you under the MIT License (MIT) and
 *  the Universal Permissive License (UPL). See the LICENSE file in the root
 *  directory for license terms. You may choose either license, or both.
 */

import Foundation
import CoreLocation

class BeaconScanner: NSObject, CLLocationManagerDelegate {
    @objc let locationManager = CLLocationManager()
    /* 
     * The `uuid` is set to the default Proximity UUID for Estimote iBeacons.
     * Modify this value to monitor beacons with other UUIDs
     */
    @objc let uuid = UUID(uuidString: "B9407F30-F5F8-466E-AFF9-25556B57FE6D")!
    
    
    override init() {
        super.init()
        locationManager.delegate = self
        if (CLLocationManager.authorizationStatus() == .authorizedAlways) {
            startScanning()
        } else {
            locationManager.requestAlwaysAuthorization()
        }
    }
    
    func locationManager(_ manager: CLLocationManager,
                         didChangeAuthorization status: CLAuthorizationStatus) {
        if status == .authorizedAlways {
            if CLLocationManager.isMonitoringAvailable(for: CLBeaconRegion.self) {
                if CLLocationManager.isRangingAvailable() {
                    startScanning()
                }
            }
        }
    }
    
    @objc func startScanning() {
        let beaconRegion = CLBeaconRegion(proximityUUID: uuid,
                                          identifier: "MyBeacon")
        locationManager.startMonitoring(for: beaconRegion)
        locationManager.startRangingBeacons(in: beaconRegion)
    }
    
    func locationManager(_ manager: CLLocationManager,
                         didRangeBeacons beacons: [CLBeacon],
                         in region: CLBeaconRegion) {
        if beacons.count > 0 {
            
            for newBeacon in beacons {
                var found = false
                for existingBeacon in beaconList {
                    if (existingBeacon.getType() == .IBEACON
                            && newBeacon.major == (existingBeacon as! IBeacon).getMajorVersionNum()
                            && newBeacon.minor == (existingBeacon as! IBeacon).getMinorVersionNum()) {
                        if (newBeacon.rssi != 0) {
                            existingBeacon.setRssi(rssi: newBeacon.rssi)
                        }
                        found = true
                    }
                }
                if !found {
                    beaconList.append(IBeacon.getInstance(majorNum: newBeacon.major,
                                                          minorNum: newBeacon.minor,
                                                          beaconUUID: newBeacon.proximityUUID))
                }
            }
            
        }
    }
}
