#ifndef WIFISENSORLINUX_H
#define WIFISENSORLINUX_H

#ifdef LINUX_DESKTOP

#include "../WiFiSensor.h"
#include <thread>

extern "C" {
	#include "WiFiSensorLinuxC.h"
}

class WiFiSensorLinux : public WiFiSensor {

private:

	std::vector<uint32_t> freqs = {2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462, 2467, 2472};
	bool running;
	std::thread thread;

	int ifIdx;
	wifiState state;

private:

	WiFiSensorLinux() {

		ifIdx = wifiGetInterfaceIndex("wlp3s0");
		if (ifIdx == 0) {throw Exception("wifi interface not found!");}

		int ret = wifiGetDriver(&state);
		if (ret != 0) {throw Exception("wifi driver not found!");}

		std::cout << "if: " << ifIdx << std::endl;

	}

public:

	/** singleton access */
	static WiFiSensorLinux& get() {
		static WiFiSensorLinux wifi;
		return wifi;
	}

	void start() override {
		running = true;
		thread = std::thread(&WiFiSensorLinux::run, this);
	}

	void stop() override {
		running = false;
		thread.join();
	}

private:

	void run() {

		wifiScanResult result;
		wifiChannels channels;
		channels.frequencies = freqs.data();
		channels.numUsed = freqs.size();



		while(running) {

			int ret;

			// trigger a scan
			ret = wifiTriggerScan(&state, ifIdx, &channels);
			if (ret != 0) {
				std::this_thread::sleep_for(std::chrono::milliseconds(100));
				continue;
			}

			// fetch scan result (blocks)
			ret = wifiGetScanResult(&state, ifIdx, &result);

			// convert to our format
			const Timestamp ts = Timestamp::fromUnixTime();
			WiFiMeasurements data;

			for (int i = 0; i < result.numUsed; ++i) {
				const std::string mac = result.entries[i].mac;
				const int rssi = result.entries[i].rssi;
				data.entries.push_back(WiFiMeasurement(AccessPoint(mac), rssi));
			}

			// and call the listeners
			informListeners(ts, data);

		}

	}

};

#endif

#endif // WIFISENSORLINUX_H
