package io.particle.android.sdk.devicesetup.loaders;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiManager;
import android.support.v4.content.AsyncTaskLoader;

import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.collect.FluentIterable;

import java.util.List;
import java.util.Set;

import io.particle.android.sdk.devicesetup.model.ScanResultNetwork;
import io.particle.android.sdk.utils.TLog;

import io.particle.android.sdk.devicesetup.R;


public class WifiScanResultLoader extends AsyncTaskLoader<Set<ScanResultNetwork>> {

    private static final TLog log = TLog.get(WifiScanResultLoader.class);


    private final WifiManager wifiManager;
    private final WifiScannedBroadcastReceiver receiver = new WifiScannedBroadcastReceiver();

    private volatile int loadCount = 0;

    public WifiScanResultLoader(Context context) {
        super(context);
        wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
    }

    @Override
    protected void onStartLoading() {
        super.onStartLoading();
        getContext().registerReceiver(receiver, receiver.buildIntentFilter());
        forceLoad();
    }

    @Override
    protected void onStopLoading() {
        getContext().unregisterReceiver(receiver);
        cancelLoad();
    }

    @Override
    public Set<ScanResultNetwork> loadInBackground() {
        List<ScanResult> scanResults = wifiManager.getScanResults();
        log.d("Latest (unfiltered) scan results: " + scanResults);

        if (loadCount % 3 == 0) {
            wifiManager.startScan();
        }

        loadCount++;
        return FluentIterable.from(scanResults)
                .filter(ssidStartsWithProductName)
                .transform(toWifiNetwork)
                .toSet();
    }


    private class WifiScannedBroadcastReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            log.d("Received WifiManager.SCAN_RESULTS_AVAILABLE_ACTION broadcast");
            forceLoad();
        }

        IntentFilter buildIntentFilter() {
            return new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
        }
    }


    private Predicate<ScanResult> ssidStartsWithProductName = new Predicate<ScanResult>() {

        final String softApPrefix = getPrefix();

        @Override
        public boolean apply(ScanResult input) {
            return input.SSID != null && input.SSID.toLowerCase().startsWith(softApPrefix);
        }

        String getPrefix() {
            return (getContext().getString(R.string.network_name_prefix)+ "-").toLowerCase();
        }

    };


    private static Function<ScanResult, ScanResultNetwork> toWifiNetwork = new Function<ScanResult, ScanResultNetwork>() {

        @Override
        public ScanResultNetwork apply(ScanResult input) {
            return new ScanResultNetwork(input);
        }
    };

}

@@ -445,16 +445,46 @@
 rable;%0A%0A
+import java.util.Collections;%0A
 import j
@@ -1711,24 +1711,190 @@
 nResults);%0A%0A
+        if (scanResults == null) %7B%0A            scanResults = Collections.emptyList();%0A            log.wtf(%22wifiManager.getScanResults() returned null??%22);%0A        %7D%0A%0A
         if (

Fix bizarro problem where WiFiManager.getScanResults() can return null?!