/*
 * Copyright (C) 2008 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 android.net.wifi;

import android.util.Log;
import android.util.Config;
import android.net.NetworkInfo;
import android.net.NetworkStateTracker;

import java.util.regex.Pattern;
import java.util.regex.Matcher;

/**
 * Listens for events from the wpa_supplicant server, and passes them on
 * to the {@link WifiStateTracker} for handling. Runs in its own thread.
 *
 * {@hide}
 */
public class WifiMonitor {

    private static final String TAG = "WifiMonitor";

    /** Events we receive from the supplicant daemon */

    private static final int CONNECTED    = 1;
    private static final int DISCONNECTED = 2;
    private static final int STATE_CHANGE = 3;
    private static final int SCAN_RESULTS = 4;
    private static final int LINK_SPEED   = 5;
    private static final int TERMINATING  = 6;
    private static final int DRIVER_STATE = 7;
    private static final int UNKNOWN      = 8;

    /** All events coming from the supplicant start with this prefix */
    private static final String eventPrefix = "CTRL-EVENT-";
    private static final int eventPrefixLen = eventPrefix.length();

    /** All WPA events coming from the supplicant start with this prefix */
    private static final String wpaEventPrefix = "WPA:";
    private static final String passwordKeyMayBeIncorrectEvent =
       "pre-shared key may be incorrect";

    /**
     * Names of events from wpa_supplicant (minus the prefix). In the
     * format descriptions, * &quot;<code>x</code>&quot;
     * designates a dynamic value that needs to be parsed out from the event
     * string
     */
    /**
     * <pre>
     * CTRL-EVENT-CONNECTED - Connection to xx:xx:xx:xx:xx:xx completed
     * </pre>
     * <code>xx:xx:xx:xx:xx:xx</code> is the BSSID of the associated access point
     */
    private static final String connectedEvent =    "CONNECTED";
    /**
     * <pre>
     * CTRL-EVENT-DISCONNECTED - Disconnect event - remove keys
     * </pre>
     */
    private static final String disconnectedEvent = "DISCONNECTED";
    /**
     * <pre>
     * CTRL-EVENT-STATE-CHANGE x
     * </pre>
     * <code>x</code> is the numerical value of the new state.
     */
    private static final String stateChangeEvent =  "STATE-CHANGE";
    /**
     * <pre>
     * CTRL-EVENT-SCAN-RESULTS ready
     * </pre>
     */
    private static final String scanResultsEvent =  "SCAN-RESULTS";

    /**
     * <pre>
     * CTRL-EVENT-LINK-SPEED x Mb/s
     * </pre>
     * {@code x} is the link speed in Mb/sec.
     */
    private static final String linkSpeedEvent = "LINK-SPEED";
    /**
     * <pre>
     * CTRL-EVENT-TERMINATING - signal x
     * </pre>
     * <code>x</code> is the signal that caused termination.
     */
    private static final String terminatingEvent =  "TERMINATING";
    /**
     * <pre>
     * CTRL-EVENT-DRIVER-STATE state
     * </pre>
     * <code>state</code> is either STARTED or STOPPED
     */
    private static final String driverStateEvent = "DRIVER-STATE";

    /**
     * Regex pattern for extracting an Ethernet-style MAC address from a string.
     * Matches a strings like the following:<pre>
     * CTRL-EVENT-CONNECTED - Connection to 00:1e:58:ec:d5:6d completed (reauth) [id=1 id_str=]</pre>
     */
    private static Pattern mConnectedEventPattern =
        Pattern.compile("((?:[0-9a-f]{2}:){5}[0-9a-f]{2}) .* \\[id=([0-9]+) ");

    private final WifiStateTracker mWifiStateTracker;

    private boolean supplicantConnected;

    private boolean oneShot;

    public WifiMonitor(WifiStateTracker tracker) {
        mWifiStateTracker = tracker;
        supplicantConnected = false;
        oneShot = true;
    }

    public void startMonitoring() {
        new MonitorThread().start();
    }

    public NetworkStateTracker getNetworkStateTracker() {
        return mWifiStateTracker;
    }

    class MonitorThread extends Thread {
        public MonitorThread() {
            super("WifiMonitor");
        }
        
        public void run() {

            //noinspection InfiniteLoopStatement
            for (;;) {
                ensureSupplicantConnection();

                String eventStr = WifiNative.waitForEvent();

                if (Config.LOGD) {
                    // Skip logging the common but mostly uninteresting scan-results event
                    if (eventStr.indexOf(scanResultsEvent) == -1) {
                        Log.v(TAG, "Event [" + eventStr +"]");
                    }
                }
                if (eventStr == null) {
                    continue;
                } else if (!eventStr.startsWith(eventPrefix)) {
                    if (eventStr.startsWith(wpaEventPrefix)) {
                        if (0 < eventStr.indexOf(passwordKeyMayBeIncorrectEvent)) {
                            handlePasswordKeyMayBeIncorrect();
                        }
                    }
                    continue;
                }

                String eventName = eventStr.substring(eventPrefixLen);
                int nameEnd = eventName.indexOf(' ');
                if (nameEnd != -1)
                    eventName = eventName.substring(0, nameEnd);
                if (eventName.length() == 0) {
                    if (Config.LOGD) Log.i(TAG, "Received wpa_supplicant event with empty event name");
                    continue;
                }
                /*
                 * Map event name into event enum
                 */
                int event;
                if (eventName.equals(connectedEvent))
                    event = CONNECTED;
                else if (eventName.equals(disconnectedEvent))
                    event = DISCONNECTED;
                else if (eventName.equals(stateChangeEvent))
                    event = STATE_CHANGE;
                else if (eventName.equals(scanResultsEvent))
                    event = SCAN_RESULTS;
                else if (eventName.equals(linkSpeedEvent))
                    event = LINK_SPEED;
                else if (eventName.equals(terminatingEvent))
                    event = TERMINATING;
                else if (eventName.equals(driverStateEvent)) {
                    event = DRIVER_STATE;
                }
                else
                    event = UNKNOWN;

                String eventData = eventStr;
                if (event == DRIVER_STATE || event == LINK_SPEED)
                    eventData = eventData.split(" ")[1];
                else if (event == STATE_CHANGE) {
                    int ind = eventStr.indexOf(" ");
                    if (ind != -1) {
                        eventData = eventStr.substring(ind + 1);
                    }
                } else {
                    int ind = eventStr.indexOf(" - ");
                    if (ind != -1) {
                        eventData = eventStr.substring(ind + 3);
                    }
                }

                if (event == STATE_CHANGE) {
                    handleSupplicantStateChange(eventData);
                } else if (event == DRIVER_STATE) {
                    handleDriverEvent(eventData);
                } else {
                    handleEvent(event, eventData);
                    // If supplicant is gone, exit the thread
                    if (event == TERMINATING) {
                        break;
                    }
                }
            }
        }

        private void ensureSupplicantConnection() {
            while (!supplicantConnected) {
                boolean connected;
                synchronized (mWifiStateTracker) {
                    connected = WifiNative.connectToSupplicant();
                }
                if (!connected) {
                    /*
                     * If we fail to connect on the very first attempt, send a message
                     * indicating a lost connection to the supplicant, so that the
                     * receiver can initialize to the proper state.
                     */
                    if (oneShot) {
                        oneShot = false;
                        mWifiStateTracker.notifySupplicantLost();
                    }
                    nap(5);
                } else {
                    supplicantConnected = true;
                    oneShot = false;
                    // Send a message indicating that it is now possible to send commands
                    // to the supplicant
                    mWifiStateTracker.notifySupplicantConnection();

                }
            }
        }

        private void handlePasswordKeyMayBeIncorrect() {
            mWifiStateTracker.notifyPasswordKeyMayBeIncorrect();
        }

        private void handleDriverEvent(String state) {
            if (state == null) {
                return;
            }
            if (state.equals("STOPPED")) {
                mWifiStateTracker.notifyDriverStopped();
            } else if (state.equals("STARTED")) {
                mWifiStateTracker.notifyDriverStarted();
            }
        }

        /**
         * Handle all supplicant events except STATE-CHANGE
         * @param event the event type
         * @param remainder the rest of the string following the
         * event name and &quot;&#8195;&#8212;&#8195;&quot;
         */
        void handleEvent(int event, String remainder) {
            switch (event) {
                case DISCONNECTED:
                    handleNetworkStateChange(NetworkInfo.DetailedState.DISCONNECTED, remainder);
                    break;

                case CONNECTED:
                    handleNetworkStateChange(NetworkInfo.DetailedState.CONNECTED, remainder);
                    break;

                case SCAN_RESULTS:
                    mWifiStateTracker.notifyScanResultsAvailable();
                    break;

                case TERMINATING:
                    supplicantConnected = false;
                    mWifiStateTracker.notifySupplicantLost();
                    break;

                case UNKNOWN:
                    break;
            }
        }

        /**
         * Handle the supplicant STATE-CHANGE event
         * @param dataString New supplicant state string in the format:
         * id=network-id state=new-state
         */
        private void handleSupplicantStateChange(String dataString) {
            String[] dataTokens = dataString.split(" ");

            int networkId = -1;
            int newState  = -1;
            for (String token : dataTokens) {
                String[] nameValue = token.split("=");
                if (nameValue.length != 2) {
                    continue;
                }

                int value;
                try {
                    value = Integer.parseInt(nameValue[1]);
                } catch (NumberFormatException e) {
                    Log.w(TAG, "STATE-CHANGE non-integer parameter: " + token);
                    continue;
                }

                if (nameValue[0].equals("id")) {
                    networkId = value;
                } else if (nameValue[0].equals("state")) {
                    newState = value;
                }
            }

            if (newState == -1) return;

            SupplicantState newSupplicantState = SupplicantState.INVALID;
            for (SupplicantState state : SupplicantState.values()) {
                if (state.ordinal() == newState) {
                    newSupplicantState = state;
                    break;
                }
            }
            if (newSupplicantState == SupplicantState.INVALID) {
                Log.w(TAG, "Invalid supplicant state: " + newState);
            }
            mWifiStateTracker.notifyStateChange(networkId, newSupplicantState);
        }
    }

    private void handleNetworkStateChange(NetworkInfo.DetailedState newState, String data) {
        String BSSID = null;
        int networkId = -1;
        if (newState == NetworkInfo.DetailedState.CONNECTED) {
            Matcher match = mConnectedEventPattern.matcher(data);
            if (!match.find()) {
                if (Config.LOGD) Log.d(TAG, "Could not find BSSID in CONNECTED event string");
            } else {
                BSSID = match.group(1);
                try {
                    networkId = Integer.parseInt(match.group(2));
                } catch (NumberFormatException e) {
                    networkId = -1;
                }
            }
        }
        mWifiStateTracker.notifyStateChange(newState, BSSID, networkId);
    }

    /**
     * Sleep for a period of time.
     * @param secs the number of seconds to sleep
     */
    private static void nap(int secs) {
        try {
            Thread.sleep(secs * 1000);
        } catch (InterruptedException e) {
        }
    }
}
