/*
 * Copyright (C) 2014 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.os.Parcelable;
import android.os.Parcel;
import android.text.TextUtils;
import java.util.HashMap;
import java.util.Date;
import java.util.ArrayList;

import java.util.BitSet;

/**
 * A class representing link layer statistics collected over a Wifi Interface.
 */
/** {@hide} */
public class WifiLinkLayerStats implements Parcelable {
    private static final String TAG = "WifiLinkLayerStats";

    /**
     * The current status of this network configuration entry.
     * @see Status
     */
    /** {@hide} */
    public int status;

    /**
     * The network's SSID. Can either be an ASCII string,
     * which must be enclosed in double quotation marks
     * (e.g., {@code "MyNetwork"}, or a string of
     * hex digits,which are not enclosed in quotes
     * (e.g., {@code 01a243f405}).
     */
    /** {@hide} */
    public String SSID;
    /**
     * When set. this is the BSSID the radio is currently associated with.
     * The value is a string in the format of an Ethernet MAC address, e.g.,
     * <code>XX:XX:XX:XX:XX:XX</code> where each <code>X</code> is a hex digit.
     */
    /** {@hide} */
    public String BSSID;

    /* number beacons received from our own AP */
    /** {@hide} */
    public int beacon_rx;

    /* RSSI taken on management frames */
    /** {@hide} */
    public int rssi_mgmt;

    /* packets counters */
    /** {@hide} */
    /* WME Best Effort Access Category (receive mpdu, transmit mpdu, lost mpdu, number of retries)*/
    public long rxmpdu_be;
    /** {@hide} */
    public long txmpdu_be;
    /** {@hide} */
    public long lostmpdu_be;
    /** {@hide} */
    public long retries_be;
    /** {@hide} */
    /* WME Background Access Category (receive mpdu, transmit mpdu, lost mpdu, number of retries) */
    public long rxmpdu_bk;
    /** {@hide} */
    public long txmpdu_bk;
    /** {@hide} */
    public long lostmpdu_bk;
    /** {@hide} */
    public long retries_bk;
    /** {@hide} */
    /* WME Video Access Category (receive mpdu, transmit mpdu, lost mpdu, number of retries) */
    public long rxmpdu_vi;
    /** {@hide} */
    public long txmpdu_vi;
    /** {@hide} */
    public long lostmpdu_vi;
    /** {@hide} */
    public long retries_vi;
    /** {@hide} */
    /* WME Voice Access Category (receive mpdu, transmit mpdu, lost mpdu, number of retries) */
    public long rxmpdu_vo;
    /** {@hide} */
    public long txmpdu_vo;
    /** {@hide} */
    public long lostmpdu_vo;
    /** {@hide} */
    public long retries_vo;


    /** {@hide} */
    public WifiLinkLayerStats() {
    }

    @Override
    /** {@hide} */
    public String toString() {
        StringBuilder sbuf = new StringBuilder();
        sbuf.append(" WifiLinkLayerStats: ").append('\n');

        if (this.SSID != null) {
            sbuf.append(" SSID: ").append(this.SSID).append('\n');
        }
        if (this.BSSID != null) {
            sbuf.append(" BSSID: ").append(this.BSSID).append('\n');
        }

        sbuf.append(" my bss beacon rx: ").append(Integer.toString(this.beacon_rx)).append('\n');
        sbuf.append(" RSSI mgmt: ").append(Integer.toString(this.rssi_mgmt)).append('\n');
        sbuf.append(" BE : ").append(" rx=").append(Long.toString(this.rxmpdu_be))
                .append(" tx=").append(Long.toString(this.txmpdu_be))
                .append(" lost=").append(Long.toString(this.lostmpdu_be))
                .append(" retries=").append(Long.toString(this.retries_be)).append('\n');
        sbuf.append(" BK : ").append(" rx=").append(Long.toString(this.rxmpdu_bk))
                .append(" tx=").append(Long.toString(this.txmpdu_bk))
                .append(" lost=").append(Long.toString(this.lostmpdu_bk))
                .append(" retries=").append(Long.toString(this.retries_bk)).append('\n');
        sbuf.append(" VI : ").append(" rx=").append(Long.toString(this.rxmpdu_vi))
                .append(" tx=").append(Long.toString(this.txmpdu_vi))
                .append(" lost=").append(Long.toString(this.lostmpdu_vi))
                .append(" retries=").append(Long.toString(this.retries_vi)).append('\n');
        sbuf.append(" VO : ").append(" rx=").append(Long.toString(this.rxmpdu_vo))
                .append(" tx=").append(Long.toString(this.txmpdu_vo))
                .append(" lost=").append(Long.toString(this.lostmpdu_vo))
                .append(" retries=").append(Long.toString(this.retries_vo)).append('\n');

        return sbuf.toString();
    }

    /** Implement the Parcelable interface {@hide} */
    public int describeContents() {
        return 0;
    }

    /** {@hide} */
    public String getPrintableSsid() {
        if (SSID == null) return "";
        final int length = SSID.length();
        if (length > 2 && (SSID.charAt(0) == '"') && SSID.charAt(length - 1) == '"') {
            return SSID.substring(1, length - 1);
        }

        /** The ascii-encoded string format is P"<ascii-encoded-string>"
         * The decoding is implemented in the supplicant for a newly configured
         * network.
         */
        if (length > 3 && (SSID.charAt(0) == 'P') && (SSID.charAt(1) == '"') &&
                (SSID.charAt(length-1) == '"')) {
            WifiSsid wifiSsid = WifiSsid.createFromAsciiEncoded(
                    SSID.substring(2, length - 1));
            return wifiSsid.toString();
        }
        return SSID;
    }

    /** Implement the Parcelable interface {@hide} */
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(SSID);
        dest.writeString(BSSID);
    }

    /** Implement the Parcelable interface {@hide} */
    public static final Creator<WifiLinkLayerStats> CREATOR =
        new Creator<WifiLinkLayerStats>() {
            public WifiLinkLayerStats createFromParcel(Parcel in) {
                WifiLinkLayerStats stats = new WifiLinkLayerStats();
                stats.SSID = in.readString();
                stats.BSSID = in.readString();
                return stats;
            };
            public WifiLinkLayerStats[] newArray(int size) {
                return new WifiLinkLayerStats[size];
            }

        };
}
