//
// © 2017-2020 Qualcomm Technologies, Inc. and/or its subsidiaries. All rights reserved.
//

import SystemConfiguration.CaptiveNetwork
import UIKit
import AFNetworking
import CocoaLumberjack

extension Notification.Name {
	static var wiFiStateDidChange = Notification.Name("WiFiStateDidChange")
}

class WiFiManager {
	// MARK: Public Properties
	static let sharedInstance = WiFiManager()
	var wifiAvailable: Bool {
		return reachability.isReachableViaWiFi
	}
	
	// MARK: Private Properties/Types
	private let reachability = AFNetworkReachabilityManager.shared()
	private struct WiFiInfo {
		static var previousIP: String?
	}
	
	// MARK: Init/Deinit
	private init() {
		startReachabilityNotifier()
	}
	
	deinit {
		stopReachabilityNotifier()
	}
}

// MARK:- Public Methods
extension WiFiManager {
	func currentWiFiIPAddress() -> String? {
		// Get list of all interfaces
		var ifaddr : UnsafeMutablePointer<ifaddrs>?
		guard getifaddrs(&ifaddr) == 0,
			let firstAddr = ifaddr else {
				return nil
		}
		defer {
			freeifaddrs(ifaddr)
		}
		
		for ifptr in sequence(first: firstAddr, next: { $0.pointee.ifa_next }) {
			let interface = ifptr.pointee
			
			// Is it IPV4 or IPV6?
			let addrFamily = interface.ifa_addr.pointee.sa_family
			if addrFamily == UInt8(AF_INET) || addrFamily == UInt8(AF_INET6) {
				
				// Is it en0?
				let name = String(cString: interface.ifa_name)
				if  name == "en0" {
					
					// Convert interface address to a human readable string
					var addr = interface.ifa_addr.pointee
					var hostname = [CChar](repeating: 0, count: Int(NI_MAXHOST))
					if getnameinfo(&addr,
								   socklen_t(interface.ifa_addr.pointee.sa_len),
								   &hostname,
								   socklen_t(hostname.count),
								   nil,
								   socklen_t(0),
								   NI_NUMERICHOST) == 0 {
						return String(cString: hostname)
					}
				}
			}
		}
		
		return nil
	}
}

// MARK:- Private Methods
extension WiFiManager {
	private func startReachabilityNotifier() {
		reachability.setReachabilityStatusChange { status in
			DispatchQueue.main.async() {
				NotificationCenter.default.post(name:.wiFiStateDidChange, object:self)
			}
		}
		reachability.startMonitoring()
	}
	
	private func stopReachabilityNotifier() {
		reachability.stopMonitoring()
	}
}


