/*
 * Copyright (C) 2011 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.p2p;

import android.annotation.IntDef;
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.compat.annotation.UnsupportedAppUsage;
import android.net.MacAddress;
import android.net.wifi.WpsInfo;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.nio.charset.StandardCharsets;
import java.util.regex.PatternSyntaxException;

/**
 * A class representing a Wi-Fi P2p configuration for setting up a connection
 *
 * {@see WifiP2pManager}
 */
public class WifiP2pConfig implements Parcelable {

    /**
     * The device MAC address uniquely identifies a Wi-Fi p2p device
     */
    public String deviceAddress = "";

    /**
     * Wi-Fi Protected Setup information
     */
    public WpsInfo wps;

    /** Get the network name of this P2P configuration, or null if unset. */
    @Nullable
    public String getNetworkName() {
        return networkName;
    }

    /** @hide */
    public String networkName = "";

    /** Get the passphrase of this P2P configuration, or null if unset. */
    @Nullable
    public String getPassphrase() {
        return passphrase;
    }

    /** @hide */
    public String passphrase = "";

    /**
     * Get the required band for the group owner.
     * The result will be one of the following:
     * {@link #GROUP_OWNER_BAND_AUTO},
     * {@link #GROUP_OWNER_BAND_2GHZ},
     * {@link #GROUP_OWNER_BAND_5GHZ}
     */
    @GroupOperatingBandType
    public int getGroupOwnerBand() {
        return groupOwnerBand;
    }

    /** @hide */
    @GroupOperatingBandType
    public int groupOwnerBand = GROUP_OWNER_BAND_AUTO;

    /** @hide */
    @IntDef(flag = false, prefix = { "GROUP_OWNER_BAND_" }, value = {
        GROUP_OWNER_BAND_AUTO,
        GROUP_OWNER_BAND_2GHZ,
        GROUP_OWNER_BAND_5GHZ
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface GroupOperatingBandType {}

    /**
     * Allow the system to pick the operating frequency from all supported bands.
     */
    public static final int GROUP_OWNER_BAND_AUTO = 0;
    /**
     * Allow the system to pick the operating frequency from the 2.4 GHz band.
     */
    public static final int GROUP_OWNER_BAND_2GHZ = 1;
    /**
     * Allow the system to pick the operating frequency from the 5 GHz band.
     */
    public static final int GROUP_OWNER_BAND_5GHZ = 2;

    /**
     * The least inclination to be a group owner, to be filled in the field
     * {@link #groupOwnerIntent}.
     */
    public static final int GROUP_OWNER_INTENT_MIN = 0;

    /**
     * The most inclination to be a group owner, to be filled in the field
     * {@link #groupOwnerIntent}.
     */
    public static final int GROUP_OWNER_INTENT_MAX = 15;

    /**
     * The system can choose an appropriate owner intent value, to be filled in the field
     * {@link #groupOwnerIntent}.
     */
    public static final int GROUP_OWNER_INTENT_AUTO = -1;

    /**
     * This is an integer value between {@link #GROUP_OWNER_INTENT_MIN} and
     * {@link #GROUP_OWNER_INTENT_MAX} where
     * {@link #GROUP_OWNER_INTENT_MIN} indicates the least inclination to be a group owner and
     * {@link #GROUP_OWNER_INTENT_MAX} indicates the highest inclination to be a group owner.
     *
     * A value of {@link #GROUP_OWNER_INTENT_AUTO} indicates the system can choose an appropriate
     * value.
     *
     * By default this field is set to {@link #GROUP_OWNER_INTENT_AUTO}.
     */
    @IntRange(from = 0, to = 15)
    public int groupOwnerIntent = GROUP_OWNER_INTENT_AUTO;

    /** @hide */
    @UnsupportedAppUsage
    public int netId = WifiP2pGroup.NETWORK_ID_PERSISTENT;

    /**
     * Get the network ID of this P2P configuration.
     * @return either a non-negative network ID, or one of
     * {@link WifiP2pGroup#NETWORK_ID_PERSISTENT} or {@link WifiP2pGroup#NETWORK_ID_TEMPORARY}.
     */
    public int getNetworkId() {
        return netId;
    }

    public WifiP2pConfig() {
        //set defaults
        wps = new WpsInfo();
        wps.setup = WpsInfo.PBC;
    }

    /** @hide */
    public void invalidate() {
        deviceAddress = "";
    }

    /** P2P-GO-NEG-REQUEST 42:fc:89:a8:96:09 dev_passwd_id=4 {@hide}*/
    @UnsupportedAppUsage
    public WifiP2pConfig(String supplicantEvent) throws IllegalArgumentException {
        String[] tokens = supplicantEvent.split(" ");

        if (tokens.length < 2 || !tokens[0].equals("P2P-GO-NEG-REQUEST")) {
            throw new IllegalArgumentException("Malformed supplicant event");
        }

        deviceAddress = tokens[1];
        wps = new WpsInfo();

        if (tokens.length > 2) {
            String[] nameVal = tokens[2].split("=");
            int devPasswdId;
            try {
                devPasswdId = Integer.parseInt(nameVal[1]);
            } catch (NumberFormatException e) {
                devPasswdId = 0;
            }
            //Based on definitions in wps/wps_defs.h
            switch (devPasswdId) {
                //DEV_PW_USER_SPECIFIED = 0x0001,
                case 0x01:
                    wps.setup = WpsInfo.DISPLAY;
                    break;
                //DEV_PW_PUSHBUTTON = 0x0004,
                case 0x04:
                    wps.setup = WpsInfo.PBC;
                    break;
                //DEV_PW_REGISTRAR_SPECIFIED = 0x0005
                case 0x05:
                    wps.setup = WpsInfo.KEYPAD;
                    break;
                default:
                    wps.setup = WpsInfo.PBC;
                    break;
            }
        }
    }

    public String toString() {
        StringBuffer sbuf = new StringBuffer();
        sbuf.append("\n address: ").append(deviceAddress);
        sbuf.append("\n wps: ").append(wps);
        sbuf.append("\n groupOwnerIntent: ").append(groupOwnerIntent);
        sbuf.append("\n persist: ").append(netId);
        sbuf.append("\n networkName: ").append(networkName);
        sbuf.append("\n passphrase: ").append(
                TextUtils.isEmpty(passphrase) ? "<empty>" : "<non-empty>");
        sbuf.append("\n groupOwnerBand: ").append(groupOwnerBand);
        return sbuf.toString();
    }

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

    /** copy constructor */
    public WifiP2pConfig(WifiP2pConfig source) {
        if (source != null) {
            deviceAddress = source.deviceAddress;
            wps = new WpsInfo(source.wps);
            groupOwnerIntent = source.groupOwnerIntent;
            netId = source.netId;
            networkName = source.networkName;
            passphrase = source.passphrase;
            groupOwnerBand = source.groupOwnerBand;
        }
    }

    /** Implement the Parcelable interface */
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(deviceAddress);
        dest.writeParcelable(wps, flags);
        dest.writeInt(groupOwnerIntent);
        dest.writeInt(netId);
        dest.writeString(networkName);
        dest.writeString(passphrase);
        dest.writeInt(groupOwnerBand);
    }

    /** Implement the Parcelable interface */
    public static final @android.annotation.NonNull Creator<WifiP2pConfig> CREATOR =
        new Creator<WifiP2pConfig>() {
            public WifiP2pConfig createFromParcel(Parcel in) {
                WifiP2pConfig config = new WifiP2pConfig();
                config.deviceAddress = in.readString();
                config.wps = (WpsInfo) in.readParcelable(null);
                config.groupOwnerIntent = in.readInt();
                config.netId = in.readInt();
                config.networkName = in.readString();
                config.passphrase = in.readString();
                config.groupOwnerBand = in.readInt();
                return config;
            }

            public WifiP2pConfig[] newArray(int size) {
                return new WifiP2pConfig[size];
            }
        };

    /**
     * Builder used to build {@link WifiP2pConfig} objects for
     * creating or joining a group.
     */
    public static final class Builder {

        private static final MacAddress MAC_ANY_ADDRESS =
                MacAddress.fromString("02:00:00:00:00:00");
        /**
         * Maximum number of bytes allowed for a SSID.
         */
        private static final int MAX_SSID_BYTES = 32;

        private MacAddress mDeviceAddress = MAC_ANY_ADDRESS;
        private String mNetworkName = "";
        private String mPassphrase = "";
        private int mGroupOperatingBand = GROUP_OWNER_BAND_AUTO;
        private int mGroupOperatingFrequency = GROUP_OWNER_BAND_AUTO;
        private int mNetId = WifiP2pGroup.NETWORK_ID_TEMPORARY;

        /**
         * Specify the peer's MAC address. If not set, the device will
         * try to find a peer whose SSID matches the network name as
         * specified by {@link #setNetworkName(String)}. Specifying null will
         * reset the peer's MAC address to "02:00:00:00:00:00".
         * <p>
         *     Optional. "02:00:00:00:00:00" by default.
         *
         * @param deviceAddress the peer's MAC address.
         * @return The builder to facilitate chaining
         *         {@code builder.setXXX(..).setXXX(..)}.
         */
        public @NonNull Builder setDeviceAddress(@Nullable MacAddress deviceAddress) {
            if (deviceAddress == null) {
                mDeviceAddress = MAC_ANY_ADDRESS;
            } else {
                mDeviceAddress = deviceAddress;
            }
            return this;
        }

        /**
         * Specify the network name, a.k.a. group name,
         * for creating or joining a group.
         * <p>
         * A network name shall begin with "DIRECT-xy". x and y are selected
         * from the following character set: upper case letters, lower case
         * letters and numbers. Any byte values allowed for an SSID according to
         * IEEE802.11-2012 [1] may be included after the string "DIRECT-xy"
         * (including none).
         * <p>
         *     Must be called - an empty network name or an network name
         *     not conforming to the P2P Group ID naming rule is not valid.
         *
         * @param networkName network name of a group.
         * @return The builder to facilitate chaining
         *         {@code builder.setXXX(..).setXXX(..)}.
         */
        public @NonNull Builder setNetworkName(@NonNull String networkName) {
            if (TextUtils.isEmpty(networkName)) {
                throw new IllegalArgumentException(
                        "network name must be non-empty.");
            }
            if (networkName.getBytes(StandardCharsets.UTF_8).length > MAX_SSID_BYTES) {
                throw new IllegalArgumentException(
                        "network name exceeds " + MAX_SSID_BYTES + " bytes.");
            }
            try {
                if (!networkName.matches("^DIRECT-[a-zA-Z0-9]{2}.*")) {
                    throw new IllegalArgumentException(
                            "network name must starts with the prefix DIRECT-xy.");
                }
            } catch (PatternSyntaxException e) {
                // can never happen (fixed pattern)
            }
            mNetworkName = networkName;
            return this;
        }

        /**
         * Specify the passphrase for creating or joining a group.
         * <p>
         * The passphrase must be an ASCII string whose length is between 8
         * and 63.
         * <p>
         *     Must be called - an empty passphrase is not valid.
         *
         * @param passphrase the passphrase of a group.
         * @return The builder to facilitate chaining
         *         {@code builder.setXXX(..).setXXX(..)}.
         */
        public @NonNull Builder setPassphrase(@NonNull String passphrase) {
            if (TextUtils.isEmpty(passphrase)) {
                throw new IllegalArgumentException(
                        "passphrase must be non-empty.");
            }
            if (passphrase.length() < 8 || passphrase.length() > 63) {
                throw new IllegalArgumentException(
                        "The length of a passphrase must be between 8 and 63.");
            }
            mPassphrase = passphrase;
            return this;
        }

        /**
         * Specify the band to use for creating the group or joining the group. The band should
         * be {@link #GROUP_OWNER_BAND_2GHZ}, {@link #GROUP_OWNER_BAND_5GHZ} or
         * {@link #GROUP_OWNER_BAND_AUTO}.
         * <p>
         * When creating a group as Group Owner using {@link
         * WifiP2pManager#createGroup(WifiP2pManager.Channel,
         * WifiP2pConfig, WifiP2pManager.ActionListener)},
         * specifying {@link #GROUP_OWNER_BAND_AUTO} allows the system to pick the operating
         * frequency from all supported bands.
         * Specifying {@link #GROUP_OWNER_BAND_2GHZ} or {@link #GROUP_OWNER_BAND_5GHZ}
         * only allows the system to pick the operating frequency in the specified band.
         * If the Group Owner cannot create a group in the specified band, the operation will fail.
         * <p>
         * When joining a group as Group Client using {@link
         * WifiP2pManager#connect(WifiP2pManager.Channel, WifiP2pConfig,
         * WifiP2pManager.ActionListener)},
         * specifying {@link #GROUP_OWNER_BAND_AUTO} allows the system to scan all supported
         * frequencies to find the desired group. Specifying {@link #GROUP_OWNER_BAND_2GHZ} or
         * {@link #GROUP_OWNER_BAND_5GHZ} only allows the system to scan the specified band.
         * <p>
         *     {@link #setGroupOperatingBand(int)} and {@link #setGroupOperatingFrequency(int)} are
         *     mutually exclusive. Setting operating band and frequency both is invalid.
         * <p>
         *     Optional. {@link #GROUP_OWNER_BAND_AUTO} by default.
         *
         * @param band the operating band of the group.
         *             This should be one of {@link #GROUP_OWNER_BAND_AUTO},
         *             {@link #GROUP_OWNER_BAND_2GHZ}, {@link #GROUP_OWNER_BAND_5GHZ}.
         * @return The builder to facilitate chaining
         *         {@code builder.setXXX(..).setXXX(..)}.
         */
        public @NonNull Builder setGroupOperatingBand(@GroupOperatingBandType int band) {
            switch (band) {
                case GROUP_OWNER_BAND_AUTO:
                case GROUP_OWNER_BAND_2GHZ:
                case GROUP_OWNER_BAND_5GHZ:
                    mGroupOperatingBand = band;
                    break;
                default:
                    throw new IllegalArgumentException(
                        "Invalid constant for the group operating band!");
            }
            return this;
        }

        /**
         * Specify the frequency, in MHz, to use for creating the group or joining the group.
         * <p>
         * When creating a group as Group Owner using {@link WifiP2pManager#createGroup(
         * WifiP2pManager.Channel, WifiP2pConfig, WifiP2pManager.ActionListener)},
         * specifying a frequency only allows the system to pick the specified frequency.
         * If the Group Owner cannot create a group at the specified frequency,
         * the operation will fail.
         * When not specifying a frequency, it allows the system to pick operating frequency
         * from all supported bands.
         * <p>
         * When joining a group as Group Client using {@link WifiP2pManager#connect(
         * WifiP2pManager.Channel, WifiP2pConfig, WifiP2pManager.ActionListener)},
         * specifying a frequency only allows the system to scan the specified frequency.
         * If the frequency is not supported or invalid, the operation will fail.
         * When not specifying a frequency, it allows the system to scan all supported
         * frequencies to find the desired group.
         * <p>
         *     {@link #setGroupOperatingBand(int)} and {@link #setGroupOperatingFrequency(int)} are
         *     mutually exclusive. Setting operating band and frequency both is invalid.
         * <p>
         *     Optional. 0 by default.
         *
         * @param frequency the operating frequency of the group.
         * @return The builder to facilitate chaining
         *         {@code builder.setXXX(..).setXXX(..)}.
         */
        public @NonNull Builder setGroupOperatingFrequency(int frequency) {
            if (frequency < 0) {
                throw new IllegalArgumentException(
                    "Invalid group operating frequency!");
            }
            mGroupOperatingFrequency = frequency;
            return this;
        }

        /**
         * Specify that the group configuration be persisted (i.e. saved).
         * By default the group configuration will not be saved.
         * <p>
         *     Optional. false by default.
         *
         * @param persistent is this group persistent group.
         * @return The builder to facilitate chaining
         *         {@code builder.setXXX(..).setXXX(..)}.
         */
        public @NonNull Builder enablePersistentMode(boolean persistent) {
            if (persistent) {
                mNetId = WifiP2pGroup.NETWORK_ID_PERSISTENT;
            } else {
                mNetId = WifiP2pGroup.NETWORK_ID_TEMPORARY;
            }
            return this;
        }

        /**
         * Build {@link WifiP2pConfig} given the current requests made on the builder.
         * @return {@link WifiP2pConfig} constructed based on builder method calls.
         */
        public @NonNull WifiP2pConfig build() {
            if (TextUtils.isEmpty(mNetworkName)) {
                throw new IllegalStateException(
                        "network name must be non-empty.");
            }
            if (TextUtils.isEmpty(mPassphrase)) {
                throw new IllegalStateException(
                        "passphrase must be non-empty.");
            }

            if (mGroupOperatingFrequency > 0 && mGroupOperatingBand > 0) {
                throw new IllegalStateException(
                        "Preferred frequency and band are mutually exclusive.");
            }

            WifiP2pConfig config = new WifiP2pConfig();
            config.deviceAddress = mDeviceAddress.toString();
            config.networkName = mNetworkName;
            config.passphrase = mPassphrase;
            config.groupOwnerBand = GROUP_OWNER_BAND_AUTO;
            if (mGroupOperatingFrequency > 0) {
                config.groupOwnerBand = mGroupOperatingFrequency;
            } else if (mGroupOperatingBand > 0) {
                config.groupOwnerBand = mGroupOperatingBand;
            }
            config.netId = mNetId;
            return config;
        }
    }
}
