/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.server.wifi;

import android.content.Context;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.text.TextUtils;
import android.util.LocalLog;
import android.util.Log;
import android.util.Pair;

import com.android.internal.annotations.VisibleForTesting;
import com.android.wifi.resources.R;

import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * This Class is a Work-In-Progress, intended behavior is as follows:
 * Essentially this class automates a user toggling 'Airplane Mode' when WiFi "won't work".
 * IF each available saved network has failed connecting more times than the FAILURE_THRESHOLD
 * THEN Watchdog will restart Supplicant, wifi driver and return ClientModeImpl to InitialState.
 */
public class WifiLastResortWatchdog {
    private static final String TAG = "WifiLastResortWatchdog";
    private boolean mVerboseLoggingEnabled = false;
    /**
     * Association Failure code
     */
    public static final int FAILURE_CODE_ASSOCIATION = 1;
    /**
     * Authentication Failure code
     */
    public static final int FAILURE_CODE_AUTHENTICATION = 2;
    /**
     * Dhcp Failure code
     */
    public static final int FAILURE_CODE_DHCP = 3;
    /**
     * Maximum number of scan results received since we last saw a BSSID.
     * If it is not seen before this limit is reached, the network is culled
     */
    public static final int MAX_BSSID_AGE = 10;
    /**
     * BSSID used to increment failure counts against ALL bssids associated with a particular SSID
     */
    public static final String BSSID_ANY = "any";
    /**
     * Failure count that each available networks must meet to possibly trigger the Watchdog
     */
    public static final int FAILURE_THRESHOLD = 7;
    public static final String BUGREPORT_TITLE = "Wifi watchdog triggered";
    public static final double PROB_TAKE_BUGREPORT_DEFAULT = 1;

    // Number of milliseconds to wait before re-enable Watchdog triger
    @VisibleForTesting
    public static final long LAST_TRIGGER_TIMEOUT_MILLIS = 2 * 3600 * 1000; // 2 hours


    /**
     * Cached WifiConfigurations of available networks seen within MAX_BSSID_AGE scan results
     * Key:BSSID, Value:Counters of failure types
     */
    private Map<String, AvailableNetworkFailureCount> mRecentAvailableNetworks = new HashMap<>();

    /**
     * Map of SSID to <FailureCount, AP count>, used to count failures & number of access points
     * belonging to an SSID.
     */
    private Map<String, Pair<AvailableNetworkFailureCount, Integer>> mSsidFailureCount =
            new HashMap<>();

    /* List of failure BSSID */
    private Set<String> mBssidFailureList = new HashSet<>();

    // Tracks: if ClientModeImpl is in ConnectedState
    private boolean mWifiIsConnected = false;
    // Is Watchdog allowed to trigger now? Set to false after triggering. Set to true after
    // successfully connecting or a new network (SSID) becomes available to connect to.
    private boolean mWatchdogAllowedToTrigger = true;
    private long mTimeLastTrigger = 0;
    private String mSsidLastTrigger = null;

    private WifiInjector mWifiInjector;
    private WifiMetrics mWifiMetrics;
    private ClientModeImpl mClientModeImpl;
    private Looper mClientModeImplLooper;
    private double mBugReportProbability = PROB_TAKE_BUGREPORT_DEFAULT;
    private Clock mClock;
    private Context mContext;
    private DeviceConfigFacade mDeviceConfigFacade;
    // If any connection failure happened after watchdog triggering restart then assume watchdog
    // did not fix the problem
    private boolean mWatchdogFixedWifi = true;
    private long mLastStartConnectTime = 0;
    private final Handler mHandler;
    private final WifiThreadRunner mWifiThreadRunner;

    private Boolean mWatchdogFeatureEnabled = null;

    /**
     * Local log used for debugging any WifiLastResortWatchdog issues.
     */
    private final LocalLog mLocalLog = new LocalLog(100);

    WifiLastResortWatchdog(WifiInjector wifiInjector, Context context, Clock clock,
            WifiMetrics wifiMetrics, ClientModeImpl clientModeImpl, Looper clientModeImplLooper,
            DeviceConfigFacade deviceConfigFacade, WifiThreadRunner wifiThreadRunner) {
        mWifiInjector = wifiInjector;
        mClock = clock;
        mWifiMetrics = wifiMetrics;
        mClientModeImpl = clientModeImpl;
        mClientModeImplLooper = clientModeImplLooper;
        mContext = context;
        mDeviceConfigFacade = deviceConfigFacade;
        mWifiThreadRunner = wifiThreadRunner;
        mHandler = new Handler(clientModeImplLooper) {
            public void handleMessage(Message msg) {
                processMessage(msg);
            }
        };
    }

    /**
     * Returns handler for L2 events from supplicant.
     * @return Handler
     */
    public Handler getHandler() {
        return mHandler;
    }

    /**
     * Refreshes when the last CMD_START_CONNECT is triggered.
     */
    public void noteStartConnectTime() {
        mHandler.post(() -> {
            mLastStartConnectTime = mClock.getElapsedSinceBootMillis();
        });
    }

    private void processMessage(Message msg) {
        switch (msg.what) {
            case WifiMonitor.NETWORK_CONNECTION_EVENT:
                // Trigger bugreport for successful connections that take abnormally long
                if (mDeviceConfigFacade.isAbnormalConnectionBugreportEnabled()
                        && mLastStartConnectTime > 0) {
                    long durationMs = mClock.getElapsedSinceBootMillis() - mLastStartConnectTime;
                    long abnormalConnectionDurationMs =
                            mDeviceConfigFacade.getAbnormalConnectionDurationMs();
                    if (durationMs > abnormalConnectionDurationMs) {
                        final String bugTitle = "Wi-Fi Bugreport: Abnormal connection time";
                        final String bugDetail = "Expected connection to take less than "
                                + abnormalConnectionDurationMs + " milliseconds. "
                                + "Actually took " + durationMs + " milliseconds.";
                        logv("Triggering bug report for abnormal connection time.");
                        mWifiThreadRunner.post(() ->
                                mClientModeImpl.takeBugReport(bugTitle, bugDetail));
                    }
                }
                // Should reset last connection time after each connection regardless if bugreport
                // is enabled or not.
                mLastStartConnectTime = 0;
                break;
            default:
                return;
        }
    }

    /**
     * Refreshes recentAvailableNetworks with the latest available networks
     * Adds new networks, removes old ones that have timed out. Should be called after Wifi
     * framework decides what networks it is potentially connecting to.
     * @param availableNetworks ScanDetail & Config list of potential connection
     * candidates
     */
    public void updateAvailableNetworks(
            List<Pair<ScanDetail, WifiConfiguration>> availableNetworks) {
        // Add new networks to mRecentAvailableNetworks
        if (availableNetworks != null) {
            if (mVerboseLoggingEnabled) {
                Log.v(TAG, "updateAvailableNetworks: size = " + availableNetworks.size());
            }
            for (Pair<ScanDetail, WifiConfiguration> pair : availableNetworks) {
                final ScanDetail scanDetail = pair.first;
                final WifiConfiguration config = pair.second;
                ScanResult scanResult = scanDetail.getScanResult();
                if (scanResult == null) continue;
                String bssid = scanResult.BSSID;
                String ssid = "\"" + scanDetail.getSSID() + "\"";
                if (mVerboseLoggingEnabled) {
                    Log.v(TAG, " " + bssid + ": " + scanDetail.getSSID());
                }
                // Cache the scanResult & WifiConfig
                AvailableNetworkFailureCount availableNetworkFailureCount =
                        mRecentAvailableNetworks.get(bssid);
                if (availableNetworkFailureCount == null) {
                    // New network is available
                    availableNetworkFailureCount = new AvailableNetworkFailureCount(config);
                    availableNetworkFailureCount.ssid = ssid;

                    // Count AP for this SSID
                    Pair<AvailableNetworkFailureCount, Integer> ssidFailsAndApCount =
                            mSsidFailureCount.get(ssid);
                    if (ssidFailsAndApCount == null) {
                        // This is a new SSID, create new FailureCount for it and set AP count to 1
                        ssidFailsAndApCount = Pair.create(new AvailableNetworkFailureCount(config),
                                1);
                        // Do not re-enable Watchdog in LAST_TRIGGER_TIMEOUT_MILLIS
                        // after last time Watchdog be triggered
                        if (!mWatchdogAllowedToTrigger && (mTimeLastTrigger == 0
                                || (mClock.getElapsedSinceBootMillis() - mTimeLastTrigger)
                                    >= LAST_TRIGGER_TIMEOUT_MILLIS)) {
                            localLog("updateAvailableNetworks: setWatchdogTriggerEnabled to true");
                            setWatchdogTriggerEnabled(true);
                        }
                    } else {
                        final Integer numberOfAps = ssidFailsAndApCount.second;
                        // This is not a new SSID, increment the AP count for it
                        ssidFailsAndApCount = Pair.create(ssidFailsAndApCount.first,
                                numberOfAps + 1);
                    }
                    mSsidFailureCount.put(ssid, ssidFailsAndApCount);
                }
                // refresh config if it is not null
                if (config != null) {
                    availableNetworkFailureCount.config = config;
                }
                // If we saw a network, set its Age to -1 here, aging iteration will set it to 0
                availableNetworkFailureCount.age = -1;
                mRecentAvailableNetworks.put(bssid, availableNetworkFailureCount);
            }
        }

        // Iterate through available networks updating timeout counts & removing networks.
        Iterator<Map.Entry<String, AvailableNetworkFailureCount>> it =
                mRecentAvailableNetworks.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry<String, AvailableNetworkFailureCount> entry = it.next();
            if (entry.getValue().age < MAX_BSSID_AGE - 1) {
                entry.getValue().age++;
            } else {
                // Decrement this SSID : AP count
                String ssid = entry.getValue().ssid;
                Pair<AvailableNetworkFailureCount, Integer> ssidFails =
                            mSsidFailureCount.get(ssid);
                if (ssidFails != null) {
                    Integer apCount = ssidFails.second - 1;
                    if (apCount > 0) {
                        ssidFails = Pair.create(ssidFails.first, apCount);
                        mSsidFailureCount.put(ssid, ssidFails);
                    } else {
                        mSsidFailureCount.remove(ssid);
                    }
                } else {
                    Log.d(TAG, "updateAvailableNetworks: SSID to AP count mismatch for " + ssid);
                }
                it.remove();
            }
        }
        if (mVerboseLoggingEnabled) Log.v(TAG, toString());
    }

    /**
     * Increments the failure reason count for the given bssid. Performs a check to see if we have
     * exceeded a failure threshold for all available networks, and executes the last resort restart
     * @param bssid of the network that has failed connection, can be "any"
     * @param reason Message id from ClientModeImpl for this failure
     * @return true if watchdog triggers, returned for test visibility
     */
    public boolean noteConnectionFailureAndTriggerIfNeeded(String ssid, String bssid, int reason) {
        if (mVerboseLoggingEnabled) {
            Log.v(TAG, "noteConnectionFailureAndTriggerIfNeeded: [" + ssid + ", " + bssid + ", "
                    + reason + "]");
        }

        // Update failure count for the failing network
        updateFailureCountForNetwork(ssid, bssid, reason);

        // If watchdog is not allowed to trigger it means a wifi restart is already triggered
        if (!mWatchdogAllowedToTrigger) {
            mWifiMetrics.incrementWatchdogTotalConnectionFailureCountAfterTrigger();
            mWatchdogFixedWifi = false;
        }
        // Have we met conditions to trigger the Watchdog Wifi restart?
        boolean isRestartNeeded = checkTriggerCondition();
        if (mVerboseLoggingEnabled) {
            Log.v(TAG, "isRestartNeeded = " + isRestartNeeded);
        }
        if (isRestartNeeded) {
            if (getWifiWatchdogFeature()) {
                // Stop the watchdog from triggering until re-enabled
                localLog("Trigger recovery: setWatchdogTriggerEnabled to false");
                setWatchdogTriggerEnabled(false);
                mWatchdogFixedWifi = true;
                loge("Watchdog triggering recovery");
                mSsidLastTrigger = ssid;
                mTimeLastTrigger = mClock.getElapsedSinceBootMillis();
                localLog(toString());
                mWifiInjector.getSelfRecovery().trigger(SelfRecovery.REASON_LAST_RESORT_WATCHDOG);
                incrementWifiMetricsTriggerCounts();
            } else {
                // auto bugreport if issue happens
                loge("bugreport notification");
                setWatchdogTriggerEnabled(false);
                takeBugReportWithCurrentProbability("Wifi Watchdog bite");
            }
        }
        return isRestartNeeded;
    }

    /**
     * Handles transitions entering and exiting ClientModeImpl ConnectedState
     * Used to track wifistate, and perform watchdog count resetting
     * @param isEntering true if called from ConnectedState.enter(), false for exit()
     */
    public void connectedStateTransition(boolean isEntering) {
        logv("connectedStateTransition: isEntering = " + isEntering);

        mWifiIsConnected = isEntering;
        if (!isEntering) {
            return;
        }
        if (!mWatchdogAllowedToTrigger && mWatchdogFixedWifi
                && getWifiWatchdogFeature()
                && checkIfAtleastOneNetworkHasEverConnected()
                && checkIfConnectedBackToSameSsid()
                && checkIfConnectedBssidHasEverFailed()) {
            takeBugReportWithCurrentProbability("Wifi fixed after restart");
            // WiFi has connected after a Watchdog trigger, without any new networks becoming
            // available, log a Watchdog success in wifi metrics
            mWifiMetrics.incrementNumLastResortWatchdogSuccesses();
            long durationMs = mClock.getElapsedSinceBootMillis() - mTimeLastTrigger;
            mWifiMetrics.setWatchdogSuccessTimeDurationMs(durationMs);
        }
        // If the watchdog trigger was disabled (it triggered), connecting means we did
        // something right, re-enable it so it can fire again.
        localLog("connectedStateTransition: setWatchdogTriggerEnabled to true");
        setWatchdogTriggerEnabled(true);
    }

    /**
     * Helper function to check if device connected to BSSID
     * which is in BSSID failure list after watchdog trigger.
     */
    private boolean checkIfConnectedBssidHasEverFailed() {
        return mBssidFailureList.contains(mClientModeImpl.getWifiInfo().getBSSID());
    }

    /**
     * Helper function to check if device connect back to same
     * SSID after watchdog trigger
     */
    private boolean checkIfConnectedBackToSameSsid() {
        if (TextUtils.equals(mSsidLastTrigger, mClientModeImpl.getWifiInfo().getSSID())) {
            return true;
        }
        localLog("checkIfConnectedBackToSameSsid: different SSID be connected");
        return false;
    }

    /**
     * Triggers a wifi specific bugreport with a based on the current trigger probability.
     * @param bugDetail description of the bug
     */
    private void takeBugReportWithCurrentProbability(String bugDetail) {
        if (mBugReportProbability <= Math.random()) {
            return;
        }
        (new Handler(mClientModeImplLooper)).post(() -> {
            mClientModeImpl.takeBugReport(BUGREPORT_TITLE, bugDetail);
        });
    }

    /**
     * Increments the failure reason count for the given network, in 'mSsidFailureCount'
     * Failures are counted per SSID, either; by using the ssid string when the bssid is "any"
     * or by looking up the ssid attached to a specific bssid
     * An unused set of counts is also kept which is bssid specific, in 'mRecentAvailableNetworks'
     * @param ssid of the network that has failed connection
     * @param bssid of the network that has failed connection, can be "any"
     * @param reason Message id from ClientModeImpl for this failure
     */
    private void updateFailureCountForNetwork(String ssid, String bssid, int reason) {
        logv("updateFailureCountForNetwork: [" + ssid + ", " + bssid + ", "
                + reason + "]");
        if (BSSID_ANY.equals(bssid)) {
            incrementSsidFailureCount(ssid, reason);
        } else {
            // Bssid count is actually unused except for logging purposes
            // SSID count is incremented within the BSSID counting method
            incrementBssidFailureCount(ssid, bssid, reason);
            mBssidFailureList.add(bssid);
        }
    }

    /**
     * Update the per-SSID failure count
     * @param ssid the ssid to increment failure count for
     * @param reason the failure type to increment count for
     */
    private void incrementSsidFailureCount(String ssid, int reason) {
        Pair<AvailableNetworkFailureCount, Integer> ssidFails = mSsidFailureCount.get(ssid);
        if (ssidFails == null) {
            Log.d(TAG, "updateFailureCountForNetwork: No networks for ssid = " + ssid);
            return;
        }
        AvailableNetworkFailureCount failureCount = ssidFails.first;
        failureCount.incrementFailureCount(reason);
    }

    /**
     * Update the per-BSSID failure count
     * @param bssid the bssid to increment failure count for
     * @param reason the failure type to increment count for
     */
    private void incrementBssidFailureCount(String ssid, String bssid, int reason) {
        AvailableNetworkFailureCount availableNetworkFailureCount =
                mRecentAvailableNetworks.get(bssid);
        if (availableNetworkFailureCount == null) {
            Log.d(TAG, "updateFailureCountForNetwork: Unable to find Network [" + ssid
                    + ", " + bssid + "]");
            return;
        }
        if (!availableNetworkFailureCount.ssid.equals(ssid)) {
            Log.d(TAG, "updateFailureCountForNetwork: Failed connection attempt has"
                    + " wrong ssid. Failed [" + ssid + ", " + bssid + "], buffered ["
                    + availableNetworkFailureCount.ssid + ", " + bssid + "]");
            return;
        }
        if (availableNetworkFailureCount.config == null) {
            if (mVerboseLoggingEnabled) {
                Log.v(TAG, "updateFailureCountForNetwork: network has no config ["
                        + ssid + ", " + bssid + "]");
            }
        }
        availableNetworkFailureCount.incrementFailureCount(reason);
        incrementSsidFailureCount(ssid, reason);
    }

    /**
     * Helper function to check if we should ignore BSSID update.
     * @param bssid BSSID of the access point
     * @return true if we should ignore BSSID update
     */
    public boolean shouldIgnoreBssidUpdate(String bssid) {
        return mWatchdogAllowedToTrigger
                && isBssidOnlyApOfSsid(bssid)
                && isSingleSsidRecorded()
                && checkIfAtleastOneNetworkHasEverConnected();
    }

    /**
     * Helper function to check if we should ignore SSID update.
     * @return true if should ignore SSID update
     */
    public boolean shouldIgnoreSsidUpdate() {
        return mWatchdogAllowedToTrigger
                && isSingleSsidRecorded()
                && checkIfAtleastOneNetworkHasEverConnected();
    }

    /**
     * Check the specified BSSID is the only BSSID for its corresponding SSID.
     * @param bssid BSSID of the access point
     * @return true if only BSSID for its corresponding SSID be observed
     */
    private boolean isBssidOnlyApOfSsid(String bssid) {
        AvailableNetworkFailureCount availableNetworkFailureCount =
                mRecentAvailableNetworks.get(bssid);
        if (availableNetworkFailureCount == null) {
            return false;
        }
        String ssid = availableNetworkFailureCount.ssid;
        Pair<AvailableNetworkFailureCount, Integer> ssidFails = mSsidFailureCount.get(ssid);
        if (ssidFails == null) {
            Log.d(TAG, "isOnlyBssidAvailable: Could not find SSID count for " + ssid);
            return false;
        }
        if (ssidFails.second != 1) {
            return false;
        }
        return true;
    }

    /**
     * Check there is only single SSID be observed.
     * @return true if only single SSID be observed.
     */
    private boolean isSingleSsidRecorded() {
        return (mSsidFailureCount.size() == 1);
    }

    /**
     * Check trigger condition: For all available networks, have we met a failure threshold for each
     * of them, and have previously connected to at-least one of the available networks
     * @return is the trigger condition true
     */
    private boolean checkTriggerCondition() {
        if (mVerboseLoggingEnabled) Log.v(TAG, "checkTriggerCondition.");
        // Don't check Watchdog trigger if wifi is in a connected state
        // (This should not occur, but we want to protect against any race conditions)
        if (mWifiIsConnected) return false;
        // Don't check Watchdog trigger if trigger is not enabled
        if (!mWatchdogAllowedToTrigger) return false;

        for (Map.Entry<String, AvailableNetworkFailureCount> entry
                : mRecentAvailableNetworks.entrySet()) {
            if (!isOverFailureThreshold(entry.getKey())) {
                // This available network is not over failure threshold, meaning we still have a
                // network to try connecting to
                return false;
            }
        }
        // We have met the failure count for every available network.
        // Trigger restart if there exists at-least one network that we have previously connected.
        boolean atleastOneNetworkHasEverConnected = checkIfAtleastOneNetworkHasEverConnected();
        logv("checkTriggerCondition: return = " + atleastOneNetworkHasEverConnected);
        return checkIfAtleastOneNetworkHasEverConnected();
    }

    private boolean checkIfAtleastOneNetworkHasEverConnected() {
        for (Map.Entry<String, AvailableNetworkFailureCount> entry
                : mRecentAvailableNetworks.entrySet()) {
            if (entry.getValue().config != null
                    && entry.getValue().config.getNetworkSelectionStatus().hasEverConnected()) {
                return true;
            }
        }
        return false;
    }

    /**
     * Update WifiMetrics with various Watchdog stats (trigger counts, failed network counts)
     */
    private void incrementWifiMetricsTriggerCounts() {
        if (mVerboseLoggingEnabled) Log.v(TAG, "incrementWifiMetricsTriggerCounts.");
        mWifiMetrics.incrementNumLastResortWatchdogTriggers();
        mWifiMetrics.addCountToNumLastResortWatchdogAvailableNetworksTotal(
                mSsidFailureCount.size());
        // Number of networks over each failure type threshold, present at trigger time
        int badAuth = 0;
        int badAssoc = 0;
        int badDhcp = 0;
        int badSum = 0;
        for (Map.Entry<String, Pair<AvailableNetworkFailureCount, Integer>> entry
                : mSsidFailureCount.entrySet()) {
            badSum = entry.getValue().first.associationRejection
                    + entry.getValue().first.authenticationFailure
                    + entry.getValue().first.dhcpFailure;
            // count as contributor if over half of badSum.
            if (badSum >= FAILURE_THRESHOLD) {
                badAssoc += (entry.getValue().first.associationRejection >= badSum / 2) ? 1 : 0;
                badAuth += (entry.getValue().first.authenticationFailure >= badSum / 2) ? 1 : 0;
                badDhcp += (entry.getValue().first.dhcpFailure >= badSum / 2) ? 1 : 0;
            }
        }
        if (badAuth > 0) {
            mWifiMetrics.addCountToNumLastResortWatchdogBadAuthenticationNetworksTotal(badAuth);
            mWifiMetrics.incrementNumLastResortWatchdogTriggersWithBadAuthentication();
        }
        if (badAssoc > 0) {
            mWifiMetrics.addCountToNumLastResortWatchdogBadAssociationNetworksTotal(badAssoc);
            mWifiMetrics.incrementNumLastResortWatchdogTriggersWithBadAssociation();
        }
        if (badDhcp > 0) {
            mWifiMetrics.addCountToNumLastResortWatchdogBadDhcpNetworksTotal(badDhcp);
            mWifiMetrics.incrementNumLastResortWatchdogTriggersWithBadDhcp();
        }
    }

    /**
     * Clear all failure counts
     */
    public void clearAllFailureCounts() {
        if (mVerboseLoggingEnabled) Log.v(TAG, "clearAllFailureCounts.");
        for (Map.Entry<String, AvailableNetworkFailureCount> entry
                : mRecentAvailableNetworks.entrySet()) {
            final AvailableNetworkFailureCount failureCount = entry.getValue();
            failureCount.resetCounts();
        }
        for (Map.Entry<String, Pair<AvailableNetworkFailureCount, Integer>> entry
                : mSsidFailureCount.entrySet()) {
            final AvailableNetworkFailureCount failureCount = entry.getValue().first;
            failureCount.resetCounts();
        }
        mBssidFailureList.clear();
    }
    /**
     * Gets the buffer of recently available networks
     */
    Map<String, AvailableNetworkFailureCount> getRecentAvailableNetworks() {
        return mRecentAvailableNetworks;
    }

    /**
     * Activates or deactivates the Watchdog trigger. Counting and network buffering still occurs
     * @param enable true to enable the Watchdog trigger, false to disable it
     */
    private void setWatchdogTriggerEnabled(boolean enable) {
        if (mVerboseLoggingEnabled) Log.v(TAG, "setWatchdogTriggerEnabled: enable = " + enable);
        // Reset failure counts before actives watchdog
        if (enable) {
            clearAllFailureCounts();
        }
        mWatchdogAllowedToTrigger = enable;
    }

    /**
     * Prints all networks & counts within mRecentAvailableNetworks to string
     */
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("mWatchdogFeatureEnabled: ").append(getWifiWatchdogFeature());
        sb.append("\nmWatchdogAllowedToTrigger: ").append(mWatchdogAllowedToTrigger);
        sb.append("\nmWifiIsConnected: ").append(mWifiIsConnected);
        sb.append("\nmRecentAvailableNetworks: ").append(mRecentAvailableNetworks.size());
        for (Map.Entry<String, AvailableNetworkFailureCount> entry
                : mRecentAvailableNetworks.entrySet()) {
            sb.append("\n ").append(entry.getKey()).append(": ").append(entry.getValue())
                .append(", Age: ").append(entry.getValue().age);
        }
        sb.append("\nmSsidFailureCount:");
        for (Map.Entry<String, Pair<AvailableNetworkFailureCount, Integer>> entry :
                mSsidFailureCount.entrySet()) {
            final AvailableNetworkFailureCount failureCount = entry.getValue().first;
            final Integer apCount = entry.getValue().second;
            sb.append("\n").append(entry.getKey()).append(": ").append(apCount).append(",")
                    .append(failureCount.toString());
        }
        return sb.toString();
    }

    /**
     * @param bssid bssid to check the failures for
     * @return true if sum of failure count is over FAILURE_THRESHOLD
     */
    public boolean isOverFailureThreshold(String bssid) {
        return (getFailureCount(bssid, FAILURE_CODE_ASSOCIATION)
                + getFailureCount(bssid, FAILURE_CODE_AUTHENTICATION)
                + getFailureCount(bssid, FAILURE_CODE_DHCP)) >= FAILURE_THRESHOLD;
    }

    /**
     * Get the failure count for a specific bssid. This actually checks the ssid attached to the
     * BSSID and returns the SSID count
     * @param reason failure reason to get count for
     */
    public int getFailureCount(String bssid, int reason) {
        AvailableNetworkFailureCount availableNetworkFailureCount =
                mRecentAvailableNetworks.get(bssid);
        if (availableNetworkFailureCount == null) {
            return 0;
        }
        String ssid = availableNetworkFailureCount.ssid;
        Pair<AvailableNetworkFailureCount, Integer> ssidFails = mSsidFailureCount.get(ssid);
        if (ssidFails == null) {
            Log.d(TAG, "getFailureCount: Could not find SSID count for " + ssid);
            return 0;
        }
        final AvailableNetworkFailureCount failCount = ssidFails.first;
        switch (reason) {
            case FAILURE_CODE_ASSOCIATION:
                return failCount.associationRejection;
            case FAILURE_CODE_AUTHENTICATION:
                return failCount.authenticationFailure;
            case FAILURE_CODE_DHCP:
                return failCount.dhcpFailure;
            default:
                return 0;
        }
    }

    /**
     * Sets whether wifi watchdog should trigger recovery
     */
    public void setWifiWatchdogFeature(boolean enable) {
        logv("setWifiWatchdogFeature: " + enable);
        mWatchdogFeatureEnabled = enable;
        // for debugging purpose, reset mWatchdogAllowedToTrigger as well
        setWatchdogTriggerEnabled(true);
    }

    /**
     * Returns whether wifi watchdog should trigger recovery.
     */
    public boolean getWifiWatchdogFeature() {
        if (mWatchdogFeatureEnabled == null) {
            mWatchdogFeatureEnabled = mContext.getResources().getBoolean(
                    R.bool.config_wifi_watchdog_enabled);
        }
        return mWatchdogFeatureEnabled;
    }

    protected void enableVerboseLogging(int verbose) {
        if (verbose > 0) {
            mVerboseLoggingEnabled = true;
        } else {
            mVerboseLoggingEnabled = false;
        }
    }

    @VisibleForTesting
    protected void setBugReportProbability(double newProbability) {
        mBugReportProbability = newProbability;
    }

    /**
     * This class holds the failure counts for an 'available network' (one of the potential
     * candidates for connection, as determined by framework).
     */
    public static class AvailableNetworkFailureCount {
        /**
         * WifiConfiguration associated with this network. Can be null for Ephemeral networks
         */
        public WifiConfiguration config;
        /**
        * SSID of the network (from ScanDetail)
        */
        public String ssid = "";
        /**
         * Number of times network has failed due to Association Rejection
         */
        public int associationRejection = 0;
        /**
         * Number of times network has failed due to Authentication Failure or SSID_TEMP_DISABLED
         */
        public int authenticationFailure = 0;
        /**
         * Number of times network has failed due to DHCP failure
         */
        public int dhcpFailure = 0;
        /**
         * Number of scanResults since this network was last seen
         */
        public int age = 0;

        AvailableNetworkFailureCount(WifiConfiguration configParam) {
            this.config = configParam;
        }

        /**
         * @param reason failure reason to increment count for
         */
        public void incrementFailureCount(int reason) {
            switch (reason) {
                case FAILURE_CODE_ASSOCIATION:
                    associationRejection++;
                    break;
                case FAILURE_CODE_AUTHENTICATION:
                    authenticationFailure++;
                    break;
                case FAILURE_CODE_DHCP:
                    dhcpFailure++;
                    break;
                default: //do nothing
            }
        }

        /**
         * Set all failure counts for this network to 0
         */
        void resetCounts() {
            associationRejection = 0;
            authenticationFailure = 0;
            dhcpFailure = 0;
        }

        public String toString() {
            return  ssid + " HasEverConnected: " + ((config != null)
                    ? config.getNetworkSelectionStatus().hasEverConnected() : "null_config")
                    + ", Failures: {"
                    + "Assoc: " + associationRejection
                    + ", Auth: " + authenticationFailure
                    + ", Dhcp: " + dhcpFailure
                    + "}";
        }
    }

    /**
     * Helper function for logging into local log buffer.
     */
    private void localLog(String s) {
        mLocalLog.log(s);
    }

    private void logv(String s) {
        mLocalLog.log(s);
        if (mVerboseLoggingEnabled) {
            Log.v(TAG, s);
        }
    }

    private void loge(String s) {
        mLocalLog.log(s);
        Log.e(TAG, s);
    }

    /**
     * Dump the local log buffer and other internal state of WifiLastResortWatchdog.
     */
    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
        pw.println("Dump of WifiLastResortWatchdog");
        pw.println("WifiLastResortWatchdog - Log Begin ----");
        mLocalLog.dump(fd, pw, args);
        pw.println("WifiLastResortWatchdog - Log End ----");
    }
}
