/*
 * 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.net.wifi.WifiConfiguration.NetworkSelectionStatus;
import android.net.wifi.WifiSsid;
import android.os.Environment;
import android.os.Process;
import android.text.TextUtils;

import android.util.LocalLog;
import android.util.Log;

import com.android.server.net.DelayedDiskWrite;

import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.text.DateFormat;
import java.util.BitSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Provides an API to read and write the network history from WifiConfigurations to file
 * This is largely separate and extra to the supplicant config file.
 */
public class WifiNetworkHistory {
    public static final String TAG = "WifiNetworkHistory";
    private static final boolean DBG = true;
    private static final boolean VDBG = true;
    static final String NETWORK_HISTORY_CONFIG_FILE = Environment.getDataDirectory()
            + "/misc/wifi/networkHistory.txt";
    /* Network History Keys */
    private static final String SSID_KEY = "SSID";
    static final String CONFIG_KEY = "CONFIG";
    private static final String CONFIG_BSSID_KEY = "CONFIG_BSSID";
    private static final String CHOICE_KEY = "CHOICE";
    private static final String CHOICE_TIME_KEY = "CHOICE_TIME";
    private static final String LINK_KEY = "LINK";
    private static final String BSSID_KEY = "BSSID";
    private static final String BSSID_KEY_END = "/BSSID";
    private static final String RSSI_KEY = "RSSI";
    private static final String FREQ_KEY = "FREQ";
    private static final String DATE_KEY = "DATE";
    private static final String MILLI_KEY = "MILLI";
    private static final String NETWORK_ID_KEY = "ID";
    private static final String PRIORITY_KEY = "PRIORITY";
    private static final String DEFAULT_GW_KEY = "DEFAULT_GW";
    private static final String AUTH_KEY = "AUTH";
    private static final String BSSID_STATUS_KEY = "BSSID_STATUS";
    private static final String SELF_ADDED_KEY = "SELF_ADDED";
    private static final String FAILURE_KEY = "FAILURE";
    private static final String DID_SELF_ADD_KEY = "DID_SELF_ADD";
    private static final String PEER_CONFIGURATION_KEY = "PEER_CONFIGURATION";
    static final String CREATOR_UID_KEY = "CREATOR_UID_KEY";
    private static final String CONNECT_UID_KEY = "CONNECT_UID_KEY";
    private static final String UPDATE_UID_KEY = "UPDATE_UID";
    private static final String FQDN_KEY = "FQDN";
    private static final String SCORER_OVERRIDE_KEY = "SCORER_OVERRIDE";
    private static final String SCORER_OVERRIDE_AND_SWITCH_KEY = "SCORER_OVERRIDE_AND_SWITCH";
    private static final String VALIDATED_INTERNET_ACCESS_KEY = "VALIDATED_INTERNET_ACCESS";
    private static final String NO_INTERNET_ACCESS_REPORTS_KEY = "NO_INTERNET_ACCESS_REPORTS";
    private static final String NO_INTERNET_ACCESS_EXPECTED_KEY = "NO_INTERNET_ACCESS_EXPECTED";
    private static final String EPHEMERAL_KEY = "EPHEMERAL";
    private static final String USE_EXTERNAL_SCORES_KEY = "USE_EXTERNAL_SCORES";
    private static final String METERED_HINT_KEY = "METERED_HINT";
    private static final String NUM_ASSOCIATION_KEY = "NUM_ASSOCIATION";
    private static final String DELETED_EPHEMERAL_KEY = "DELETED_EPHEMERAL";
    private static final String CREATOR_NAME_KEY = "CREATOR_NAME";
    private static final String UPDATE_NAME_KEY = "UPDATE_NAME";
    private static final String USER_APPROVED_KEY = "USER_APPROVED";
    private static final String CREATION_TIME_KEY = "CREATION_TIME";
    private static final String UPDATE_TIME_KEY = "UPDATE_TIME";
    static final String SHARED_KEY = "SHARED";
    private static final String NETWORK_SELECTION_STATUS_KEY = "NETWORK_SELECTION_STATUS";
    private static final String NETWORK_SELECTION_DISABLE_REASON_KEY =
            "NETWORK_SELECTION_DISABLE_REASON";
    private static final String HAS_EVER_CONNECTED_KEY = "HAS_EVER_CONNECTED";

    private static final String SEPARATOR = ":  ";
    private static final String NL = "\n";

    protected final DelayedDiskWrite mWriter;
    Context mContext;
    private final LocalLog mLocalLog;
    /*
     * Lost config list, whenever we read a config from networkHistory.txt that was not in
     * wpa_supplicant.conf
     */
    HashSet<String> mLostConfigsDbg = new HashSet<String>();

    public WifiNetworkHistory(Context c, LocalLog localLog, DelayedDiskWrite writer) {
        mContext = c;
        mWriter = writer;
        mLocalLog = localLog;
    }

    /**
     * Write network history to file, for configured networks
     *
     * @param networks List of ConfiguredNetworks to write to NetworkHistory
     */
    public void writeKnownNetworkHistory(final List<WifiConfiguration> networks,
            final ConcurrentHashMap<Integer, ScanDetailCache> scanDetailCaches,
            final Set<String> deletedEphemeralSSIDs) {

        /* Make a copy */
        //final List<WifiConfiguration> networks = new ArrayList<WifiConfiguration>();

        //for (WifiConfiguration config : mConfiguredNetworks.valuesForAllUsers()) {
        //    networks.add(new WifiConfiguration(config));
        //}

        mWriter.write(NETWORK_HISTORY_CONFIG_FILE, new DelayedDiskWrite.Writer() {
            public void onWriteCalled(DataOutputStream out) throws IOException {
                for (WifiConfiguration config : networks) {
                    //loge("onWriteCalled write SSID: " + config.SSID);
                   /* if (config.getLinkProperties() != null)
                        loge(" lp " + config.getLinkProperties().toString());
                    else
                        loge("attempt config w/o lp");
                    */
                    NetworkSelectionStatus status = config.getNetworkSelectionStatus();
                    if (VDBG) {
                        int numlink = 0;
                        if (config.linkedConfigurations != null) {
                            numlink = config.linkedConfigurations.size();
                        }
                        String disableTime;
                        if (config.getNetworkSelectionStatus().isNetworkEnabled()) {
                            disableTime = "";
                        } else {
                            disableTime = "Disable time: " + DateFormat.getInstance().format(
                                    config.getNetworkSelectionStatus().getDisableTime());
                        }
                        logd("saving network history: " + config.configKey()  + " gw: "
                                + config.defaultGwMacAddress + " Network Selection-status: "
                                + status.getNetworkStatusString()
                                + disableTime + " ephemeral=" + config.ephemeral
                                + " choice:" + status.getConnectChoice()
                                + " link:" + numlink
                                + " status:" + config.status
                                + " nid:" + config.networkId
                                + " hasEverConnected: " + status.getHasEverConnected());
                    }

                    if (!isValid(config)) {
                        continue;
                    }

                    if (config.SSID == null) {
                        if (VDBG) {
                            logv("writeKnownNetworkHistory trying to write config with null SSID");
                        }
                        continue;
                    }
                    if (VDBG) {
                        logv("writeKnownNetworkHistory write config " + config.configKey());
                    }
                    out.writeUTF(CONFIG_KEY + SEPARATOR + config.configKey() + NL);

                    if (config.SSID != null) {
                        out.writeUTF(SSID_KEY + SEPARATOR + config.SSID + NL);
                    }
                    if (config.BSSID != null) {
                        out.writeUTF(CONFIG_BSSID_KEY + SEPARATOR + config.BSSID + NL);
                    } else {
                        out.writeUTF(CONFIG_BSSID_KEY + SEPARATOR + "null" + NL);
                    }
                    if (config.FQDN != null) {
                        out.writeUTF(FQDN_KEY + SEPARATOR + config.FQDN + NL);
                    }

                    out.writeUTF(PRIORITY_KEY + SEPARATOR + Integer.toString(config.priority) + NL);
                    out.writeUTF(NETWORK_ID_KEY + SEPARATOR
                            + Integer.toString(config.networkId) + NL);
                    out.writeUTF(SELF_ADDED_KEY + SEPARATOR
                            + Boolean.toString(config.selfAdded) + NL);
                    out.writeUTF(DID_SELF_ADD_KEY + SEPARATOR
                            + Boolean.toString(config.didSelfAdd) + NL);
                    out.writeUTF(NO_INTERNET_ACCESS_REPORTS_KEY + SEPARATOR
                            + Integer.toString(config.numNoInternetAccessReports) + NL);
                    out.writeUTF(VALIDATED_INTERNET_ACCESS_KEY + SEPARATOR
                            + Boolean.toString(config.validatedInternetAccess) + NL);
                    out.writeUTF(NO_INTERNET_ACCESS_EXPECTED_KEY + SEPARATOR +
                            Boolean.toString(config.noInternetAccessExpected) + NL);
                    out.writeUTF(EPHEMERAL_KEY + SEPARATOR
                            + Boolean.toString(config.ephemeral) + NL);
                    out.writeUTF(METERED_HINT_KEY + SEPARATOR
                            + Boolean.toString(config.meteredHint) + NL);
                    out.writeUTF(USE_EXTERNAL_SCORES_KEY + SEPARATOR
                            + Boolean.toString(config.useExternalScores) + NL);
                    if (config.creationTime != null) {
                        out.writeUTF(CREATION_TIME_KEY + SEPARATOR + config.creationTime + NL);
                    }
                    if (config.updateTime != null) {
                        out.writeUTF(UPDATE_TIME_KEY + SEPARATOR + config.updateTime + NL);
                    }
                    if (config.peerWifiConfiguration != null) {
                        out.writeUTF(PEER_CONFIGURATION_KEY + SEPARATOR
                                + config.peerWifiConfiguration + NL);
                    }
                    out.writeUTF(SCORER_OVERRIDE_KEY + SEPARATOR
                            + Integer.toString(config.numScorerOverride) + NL);
                    out.writeUTF(SCORER_OVERRIDE_AND_SWITCH_KEY + SEPARATOR
                            + Integer.toString(config.numScorerOverrideAndSwitchedNetwork) + NL);
                    out.writeUTF(NUM_ASSOCIATION_KEY + SEPARATOR
                            + Integer.toString(config.numAssociation) + NL);
                    out.writeUTF(CREATOR_UID_KEY + SEPARATOR
                            + Integer.toString(config.creatorUid) + NL);
                    out.writeUTF(CONNECT_UID_KEY + SEPARATOR
                            + Integer.toString(config.lastConnectUid) + NL);
                    out.writeUTF(UPDATE_UID_KEY + SEPARATOR
                            + Integer.toString(config.lastUpdateUid) + NL);
                    out.writeUTF(CREATOR_NAME_KEY + SEPARATOR
                            + config.creatorName + NL);
                    out.writeUTF(UPDATE_NAME_KEY + SEPARATOR
                            + config.lastUpdateName + NL);
                    out.writeUTF(USER_APPROVED_KEY + SEPARATOR
                            + Integer.toString(config.userApproved) + NL);
                    out.writeUTF(SHARED_KEY + SEPARATOR + Boolean.toString(config.shared) + NL);
                    String allowedKeyManagementString =
                            makeString(config.allowedKeyManagement,
                                    WifiConfiguration.KeyMgmt.strings);
                    out.writeUTF(AUTH_KEY + SEPARATOR
                            + allowedKeyManagementString + NL);
                    out.writeUTF(NETWORK_SELECTION_STATUS_KEY + SEPARATOR
                            + status.getNetworkSelectionStatus() + NL);
                    out.writeUTF(NETWORK_SELECTION_DISABLE_REASON_KEY + SEPARATOR
                            + status.getNetworkSelectionDisableReason() + NL);

                    if (status.getConnectChoice() != null) {
                        out.writeUTF(CHOICE_KEY + SEPARATOR + status.getConnectChoice() + NL);
                        out.writeUTF(CHOICE_TIME_KEY + SEPARATOR
                                + status.getConnectChoiceTimestamp() + NL);
                    }

                    if (config.linkedConfigurations != null) {
                        log("writeKnownNetworkHistory write linked "
                                + config.linkedConfigurations.size());

                        for (String key : config.linkedConfigurations.keySet()) {
                            out.writeUTF(LINK_KEY + SEPARATOR + key + NL);
                        }
                    }

                    String macAddress = config.defaultGwMacAddress;
                    if (macAddress != null) {
                        out.writeUTF(DEFAULT_GW_KEY + SEPARATOR + macAddress + NL);
                    }

                    if (getScanDetailCache(config, scanDetailCaches) != null) {
                        for (ScanDetail scanDetail : getScanDetailCache(config,
                                    scanDetailCaches).values()) {
                            ScanResult result = scanDetail.getScanResult();
                            out.writeUTF(BSSID_KEY + SEPARATOR
                                    + result.BSSID + NL);
                            out.writeUTF(FREQ_KEY + SEPARATOR
                                    + Integer.toString(result.frequency) + NL);

                            out.writeUTF(RSSI_KEY + SEPARATOR
                                    + Integer.toString(result.level) + NL);

                            out.writeUTF(BSSID_KEY_END + NL);
                        }
                    }
                    if (config.lastFailure != null) {
                        out.writeUTF(FAILURE_KEY + SEPARATOR + config.lastFailure + NL);
                    }
                    out.writeUTF(HAS_EVER_CONNECTED_KEY + SEPARATOR
                            + Boolean.toString(status.getHasEverConnected()) + NL);
                    out.writeUTF(NL);
                    // Add extra blank lines for clarity
                    out.writeUTF(NL);
                    out.writeUTF(NL);
                }
                if (deletedEphemeralSSIDs != null && deletedEphemeralSSIDs.size() > 0) {
                    for (String ssid : deletedEphemeralSSIDs) {
                        out.writeUTF(DELETED_EPHEMERAL_KEY);
                        out.writeUTF(ssid);
                        out.writeUTF(NL);
                    }
                }
            }
        });
    }

    /**
     * Adds information stored in networkHistory.txt to the given configs. The configs are provided
     * as a mapping from configKey to WifiConfiguration, because the WifiConfigurations themselves
     * do not contain sufficient information to compute their configKeys until after the information
     * that is stored in networkHistory.txt has been added to them.
     *
     * @param configs mapping from configKey to a WifiConfiguration that contains the information
     *         information read from wpa_supplicant.conf
     */
    public void readNetworkHistory(Map<String, WifiConfiguration> configs,
            Map<Integer, ScanDetailCache> scanDetailCaches,
            Set<String> deletedEphemeralSSIDs) {
        localLog("readNetworkHistory() path:" + NETWORK_HISTORY_CONFIG_FILE);

        try (DataInputStream in =
                     new DataInputStream(new BufferedInputStream(
                             new FileInputStream(NETWORK_HISTORY_CONFIG_FILE)))) {

            String bssid = null;
            String ssid = null;

            int freq = 0;
            int status = 0;
            long seen = 0;
            int rssi = WifiConfiguration.INVALID_RSSI;
            String caps = null;

            WifiConfiguration config = null;
            while (true) {
                String line = in.readUTF();
                if (line == null) {
                    break;
                }
                int colon = line.indexOf(':');
                if (colon < 0) {
                    continue;
                }

                String key = line.substring(0, colon).trim();
                String value = line.substring(colon + 1).trim();

                if (key.equals(CONFIG_KEY)) {
                    config = configs.get(value);

                    // skip reading that configuration data
                    // since we don't have a corresponding network ID
                    if (config == null) {
                        localLog("readNetworkHistory didnt find netid for hash="
                                + Integer.toString(value.hashCode())
                                + " key: " + value);
                        mLostConfigsDbg.add(value);
                        continue;
                    } else {
                        // After an upgrade count old connections as owned by system
                        if (config.creatorName == null || config.lastUpdateName == null) {
                            config.creatorName =
                                mContext.getPackageManager().getNameForUid(Process.SYSTEM_UID);
                            config.lastUpdateName = config.creatorName;

                            if (DBG) {
                                Log.w(TAG, "Upgrading network " + config.networkId
                                        + " to " + config.creatorName);
                            }
                        }
                    }
                } else if (config != null) {
                    NetworkSelectionStatus networkStatus = config.getNetworkSelectionStatus();
                    switch (key) {
                        case SSID_KEY:
                            if (config.isPasspoint()) {
                                break;
                            }
                            ssid = value;
                            if (config.SSID != null && !config.SSID.equals(ssid)) {
                                loge("Error parsing network history file, mismatched SSIDs");
                                config = null; //error
                                ssid = null;
                            } else {
                                config.SSID = ssid;
                            }
                            break;
                        case CONFIG_BSSID_KEY:
                            config.BSSID = value.equals("null") ? null : value;
                            break;
                        case FQDN_KEY:
                            // Check for literal 'null' to be backwards compatible.
                            config.FQDN = value.equals("null") ? null : value;
                            break;
                        case DEFAULT_GW_KEY:
                            config.defaultGwMacAddress = value;
                            break;
                        case SELF_ADDED_KEY:
                            config.selfAdded = Boolean.parseBoolean(value);
                            break;
                        case DID_SELF_ADD_KEY:
                            config.didSelfAdd = Boolean.parseBoolean(value);
                            break;
                        case NO_INTERNET_ACCESS_REPORTS_KEY:
                            config.numNoInternetAccessReports = Integer.parseInt(value);
                            break;
                        case VALIDATED_INTERNET_ACCESS_KEY:
                            config.validatedInternetAccess = Boolean.parseBoolean(value);
                            break;
                        case NO_INTERNET_ACCESS_EXPECTED_KEY:
                            config.noInternetAccessExpected = Boolean.parseBoolean(value);
                            break;
                        case CREATION_TIME_KEY:
                            config.creationTime = value;
                            break;
                        case UPDATE_TIME_KEY:
                            config.updateTime = value;
                            break;
                        case EPHEMERAL_KEY:
                            config.ephemeral = Boolean.parseBoolean(value);
                            break;
                        case METERED_HINT_KEY:
                            config.meteredHint = Boolean.parseBoolean(value);
                            break;
                        case USE_EXTERNAL_SCORES_KEY:
                            config.useExternalScores = Boolean.parseBoolean(value);
                            break;
                        case CREATOR_UID_KEY:
                            config.creatorUid = Integer.parseInt(value);
                            break;
                        case SCORER_OVERRIDE_KEY:
                            config.numScorerOverride = Integer.parseInt(value);
                            break;
                        case SCORER_OVERRIDE_AND_SWITCH_KEY:
                            config.numScorerOverrideAndSwitchedNetwork = Integer.parseInt(value);
                            break;
                        case NUM_ASSOCIATION_KEY:
                            config.numAssociation = Integer.parseInt(value);
                            break;
                        case CONNECT_UID_KEY:
                            config.lastConnectUid = Integer.parseInt(value);
                            break;
                        case UPDATE_UID_KEY:
                            config.lastUpdateUid = Integer.parseInt(value);
                            break;
                        case FAILURE_KEY:
                            config.lastFailure = value;
                            break;
                        case PEER_CONFIGURATION_KEY:
                            config.peerWifiConfiguration = value;
                            break;
                        case NETWORK_SELECTION_STATUS_KEY:
                            int networkStatusValue = Integer.parseInt(value);
                            // Reset temporarily disabled network status
                            if (networkStatusValue ==
                                    NetworkSelectionStatus.NETWORK_SELECTION_TEMPORARY_DISABLED) {
                                networkStatusValue =
                                        NetworkSelectionStatus.NETWORK_SELECTION_ENABLED;
                            }
                            networkStatus.setNetworkSelectionStatus(networkStatusValue);
                            break;
                        case NETWORK_SELECTION_DISABLE_REASON_KEY:
                            networkStatus.setNetworkSelectionDisableReason(Integer.parseInt(value));
                            break;
                        case CHOICE_KEY:
                            networkStatus.setConnectChoice(value);
                            break;
                        case CHOICE_TIME_KEY:
                            networkStatus.setConnectChoiceTimestamp(Long.parseLong(value));
                            break;
                        case LINK_KEY:
                            if (config.linkedConfigurations == null) {
                                config.linkedConfigurations = new HashMap<>();
                            } else {
                                config.linkedConfigurations.put(value, -1);
                            }
                            break;
                        case BSSID_KEY:
                            status = 0;
                            ssid = null;
                            bssid = null;
                            freq = 0;
                            seen = 0;
                            rssi = WifiConfiguration.INVALID_RSSI;
                            caps = "";
                            break;
                        case RSSI_KEY:
                            rssi = Integer.parseInt(value);
                            break;
                        case FREQ_KEY:
                            freq = Integer.parseInt(value);
                            break;
                        case DATE_KEY:
                            /*
                             * when reading the configuration from file we don't update the date
                             * so as to avoid reading back stale or non-sensical data that would
                             * depend on network time.
                             * The date of a WifiConfiguration should only come from actual scan
                             * result.
                             *
                            String s = key.replace(FREQ_KEY, "");
                            seen = Integer.getInteger(s);
                            */
                            break;
                        case BSSID_KEY_END:
                            if ((bssid != null) && (ssid != null)) {
                                if (getScanDetailCache(config, scanDetailCaches) != null) {
                                    WifiSsid wssid = WifiSsid.createFromAsciiEncoded(ssid);
                                    ScanDetail scanDetail = new ScanDetail(wssid, bssid,
                                            caps, rssi, freq, (long) 0, seen);
                                    getScanDetailCache(config, scanDetailCaches).put(scanDetail);
                                }
                            }
                            break;
                        case DELETED_EPHEMERAL_KEY:
                            if (!TextUtils.isEmpty(value)) {
                                deletedEphemeralSSIDs.add(value);
                            }
                            break;
                        case CREATOR_NAME_KEY:
                            config.creatorName = value;
                            break;
                        case UPDATE_NAME_KEY:
                            config.lastUpdateName = value;
                            break;
                        case USER_APPROVED_KEY:
                            config.userApproved = Integer.parseInt(value);
                            break;
                        case SHARED_KEY:
                            config.shared = Boolean.parseBoolean(value);
                            break;
                        case HAS_EVER_CONNECTED_KEY:
                            networkStatus.setHasEverConnected(Boolean.parseBoolean(value));
                            break;
                    }
                }
            }
        } catch (EOFException e) {
            // do nothing
        } catch (FileNotFoundException e) {
            Log.i(TAG, "readNetworkHistory: no config file, " + e);
        } catch (NumberFormatException e) {
            Log.e(TAG, "readNetworkHistory: failed to parse, " + e, e);
        } catch (IOException e) {
            Log.e(TAG, "readNetworkHistory: failed to read, " + e, e);
        }
    }

    /**
     * Ported this out of WifiServiceImpl, I have no idea what it's doing
     * <TODO> figure out what/why this is doing
     * <TODO> Port it into WifiConfiguration, then remove all the silly business from ServiceImpl
     */
    public boolean isValid(WifiConfiguration config) {
        if (config.allowedKeyManagement == null) {
            return false;
        }
        if (config.allowedKeyManagement.cardinality() > 1) {
            if (config.allowedKeyManagement.cardinality() != 2) {
                return false;
            }
            if (!config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.WPA_EAP)) {
                return false;
            }
            if ((!config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.IEEE8021X))
                    && (!config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.WPA_PSK))) {
                return false;
            }
        }
        return true;
    }

    private static String makeString(BitSet set, String[] strings) {
        StringBuffer buf = new StringBuffer();
        int nextSetBit = -1;

        /* Make sure all set bits are in [0, strings.length) to avoid
         * going out of bounds on strings.  (Shouldn't happen, but...) */
        set = set.get(0, strings.length);

        while ((nextSetBit = set.nextSetBit(nextSetBit + 1)) != -1) {
            buf.append(strings[nextSetBit].replace('_', '-')).append(' ');
        }

        // remove trailing space
        if (set.cardinality() > 0) {
            buf.setLength(buf.length() - 1);
        }

        return buf.toString();
    }

    protected void logv(String s) {
        Log.v(TAG, s);
    }
    protected void logd(String s) {
        Log.d(TAG, s);
    }
    protected void log(String s) {
        Log.d(TAG, s);
    }
    protected void loge(String s) {
        loge(s, false);
    }
    protected void loge(String s, boolean stack) {
        if (stack) {
            Log.e(TAG, s + " stack:" + Thread.currentThread().getStackTrace()[2].getMethodName()
                    + " - " + Thread.currentThread().getStackTrace()[3].getMethodName()
                    + " - " + Thread.currentThread().getStackTrace()[4].getMethodName()
                    + " - " + Thread.currentThread().getStackTrace()[5].getMethodName());
        } else {
            Log.e(TAG, s);
        }
    }

    private void localLog(String s) {
        if (mLocalLog != null) {
            mLocalLog.log(s);
        }
    }

    private ScanDetailCache getScanDetailCache(WifiConfiguration config,
            Map<Integer, ScanDetailCache> scanDetailCaches) {
        if (config == null || scanDetailCaches == null) return null;
        ScanDetailCache cache = scanDetailCaches.get(config.networkId);
        if (cache == null && config.networkId != WifiConfiguration.INVALID_NETWORK_ID) {
            cache =
                    new ScanDetailCache(
                            config, WifiConfigManager.SCAN_CACHE_ENTRIES_MAX_SIZE,
                            WifiConfigManager.SCAN_CACHE_ENTRIES_TRIM_SIZE);
            scanDetailCaches.put(config.networkId, cache);
        }
        return cache;
    }
}
