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

import android.compat.annotation.UnsupportedAppUsage;
import android.net.wifi.p2p.WifiP2pManager;
import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;

import java.util.Locale;

/**
 * A class for creating a service discovery request for use with
 * {@link WifiP2pManager#addServiceRequest} and {@link WifiP2pManager#removeServiceRequest}
 *
 * <p>This class is used to create service discovery request for custom
 * vendor specific service discovery protocol {@link WifiP2pServiceInfo#SERVICE_TYPE_VENDOR_SPECIFIC}
 * or to search all service protocols {@link WifiP2pServiceInfo#SERVICE_TYPE_ALL}.
 *
 * <p>For the purpose of creating a UPnP or Bonjour service request, use
 * {@link WifiP2pUpnpServiceRequest} or {@link WifiP2pDnsSdServiceRequest} respectively.
 *
 * {@see WifiP2pManager}
 * {@see WifiP2pUpnpServiceRequest}
 * {@see WifiP2pDnsSdServiceRequest}
 */
public class WifiP2pServiceRequest implements Parcelable {

    /**
     * Service discovery protocol. It's defined in table63 in Wi-Fi Direct specification.
     */
    private int mProtocolType;

    /**
     * The length of the service request TLV.
     * The value is equal to 2 plus the number of octets in the
     * query data field.
     */
    private int mLength;

    /**
     * Service transaction ID.
     * This is a nonzero value used to match the service request/response TLVs.
     */
    private int mTransId;

    /**
     * The hex dump string of query data for the requested service information.
     *
     * e.g) DnsSd apple file sharing over tcp (dns name=_afpovertcp._tcp.local.)
     * 0b5f6166706f766572746370c00c000c01
     */
    private String mQuery;

    /**
     * This constructor is only used in newInstance().
     *
     * @param protocolType service discovery protocol.
     * @param query The part of service specific query.
     * @hide
     */
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
    protected WifiP2pServiceRequest(int protocolType, String query) {
        validateQuery(query);

        mProtocolType = protocolType;
        mQuery = query;
        if (query != null) {
            mLength = query.length()/2 + 2;
        } else {
            mLength = 2;
        }
    }

    /**
     * This constructor is only used in Parcelable.
     *
     * @param serviceType service discovery type.
     * @param length the length of service discovery packet.
     * @param transId the transaction id
     * @param query The part of service specific query.
     */
    private WifiP2pServiceRequest(int serviceType, int length,
            int transId, String query) {
        mProtocolType = serviceType;
        mLength = length;
        mTransId = transId;
        mQuery = query;
    }

    /**
     * Return transaction id.
     *
     * @return transaction id
     * @hide
     */
    public int getTransactionId() {
        return mTransId;
    }

    /**
     * Set transaction id.
     *
     * @param id
     * @hide
     */
    public void setTransactionId(int id) {
        mTransId = id;
    }

    /**
     * Return wpa_supplicant request string.
     *
     * The format is the hex dump of the following frame.
     * <pre>
     * _______________________________________________________________
     * |        Length (2)        |   Type (1)   | Transaction ID (1) |
     * |                  Query Data (variable)                       |
     * </pre>
     *
     * @return wpa_supplicant request string.
     * @hide
     */
    public String getSupplicantQuery() {
        StringBuffer sb = new StringBuffer();
        // length is retained as little endian format.
        sb.append(String.format(Locale.US, "%02x", (mLength) & 0xff));
        sb.append(String.format(Locale.US, "%02x", (mLength >> 8) & 0xff));
        sb.append(String.format(Locale.US, "%02x", mProtocolType));
        sb.append(String.format(Locale.US, "%02x", mTransId));
        if (mQuery != null) {
            sb.append(mQuery);
        }

        return sb.toString();
    }

    /**
     * Validate query.
     *
     * <p>If invalid, throw IllegalArgumentException.
     * @param query The part of service specific query.
     */
    private void validateQuery(String query) {
        if (query == null) {
            return;
        }

        int UNSIGNED_SHORT_MAX = 0xffff;
        if (query.length()%2 == 1) {
            throw new IllegalArgumentException(
                    "query size is invalid. query=" + query);
        }
        if (query.length()/2 > UNSIGNED_SHORT_MAX) {
            throw new IllegalArgumentException(
                    "query size is too large. len=" + query.length());
        }

        // check whether query is hex string.
        query = query.toLowerCase(Locale.ROOT);
        char[] chars = query.toCharArray();
        for (char c: chars) {
            if (!((c >= '0' && c <= '9') ||
                    (c >= 'a' && c <= 'f'))){
                throw new IllegalArgumentException(
                        "query should be hex string. query=" + query);
            }
        }
    }

    /**
     * Create a service discovery request.
     *
     * @param protocolType can be {@link WifiP2pServiceInfo#SERVICE_TYPE_ALL}
     * or {@link WifiP2pServiceInfo#SERVICE_TYPE_VENDOR_SPECIFIC}.
     * In order to create a UPnP or Bonjour service request, use
     * {@link WifiP2pUpnpServiceRequest} or {@link WifiP2pDnsSdServiceRequest}
     * respectively
     *
     * @param queryData hex string that is vendor specific.  Can be null.
     * @return service discovery request.
     */
    public static WifiP2pServiceRequest newInstance(int protocolType, String queryData) {
        return new WifiP2pServiceRequest(protocolType, queryData);
    }

    /**
     * Create a service discovery request.
     *
     * @param protocolType can be {@link WifiP2pServiceInfo#SERVICE_TYPE_ALL}
     * or {@link WifiP2pServiceInfo#SERVICE_TYPE_VENDOR_SPECIFIC}.
     * In order to create a UPnP or Bonjour service request, use
     * {@link WifiP2pUpnpServiceRequest} or {@link WifiP2pDnsSdServiceRequest}
     * respectively
     *
     * @return service discovery request.
     */
    public static WifiP2pServiceRequest newInstance(int protocolType ) {
        return new WifiP2pServiceRequest(protocolType, null);
    }

    @Override
    public boolean equals(Object o) {
        if (o == this) {
            return true;
        }
        if (!(o instanceof WifiP2pServiceRequest)) {
            return false;
        }

        WifiP2pServiceRequest req = (WifiP2pServiceRequest)o;

        /*
         * Not compare transaction id.
         * Transaction id may be changed on each service discovery operation.
         */
        if ((req.mProtocolType != mProtocolType) ||
                (req.mLength != mLength)) {
            return false;
        }

        if (req.mQuery == null && mQuery == null) {
            return true;
        } else if (req.mQuery != null) {
            return req.mQuery.equals(mQuery);
        }
        return false;
   }

    @Override
    public int hashCode() {
        int result = 17;
        result = 31 * result + mProtocolType;
        result = 31 * result + mLength;
        result = 31 * result + (mQuery == null ? 0 : mQuery.hashCode());
        return result;
    }

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

    /** Implement the Parcelable interface {@hide} */
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(mProtocolType);
        dest.writeInt(mLength);
        dest.writeInt(mTransId);
        dest.writeString(mQuery);
    }

    /** Implement the Parcelable interface {@hide} */
    @UnsupportedAppUsage
    public static final @android.annotation.NonNull Creator<WifiP2pServiceRequest> CREATOR =
        new Creator<WifiP2pServiceRequest>() {
            public WifiP2pServiceRequest createFromParcel(Parcel in) {
                int servType = in.readInt();
                int length = in.readInt();
                int transId = in.readInt();
                String query = in.readString();
                return new WifiP2pServiceRequest(servType, length, transId, query);
            }

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