/*
 * Copyright (c) 2014 The Android Open Source Project
 * Copyright (c) 2008-2009, Motorola, Inc.
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * - Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * - Neither the name of the Motorola, Inc. nor the names of its contributors
 * may be used to endorse or promote products derived from this software
 * without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

package javax.obex;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Calendar;
import java.security.SecureRandom;

/**
 * This class implements the javax.obex.HeaderSet interface for OBEX over
 * RFCOMM or OBEX over l2cap.
 * @hide
 */
public final class HeaderSet {

    /**
     * Represents the OBEX Count header. This allows the connection statement to
     * tell the server how many objects it plans to send or retrieve.
     * <P>
     * The value of <code>COUNT</code> is 0xC0 (192).
     */
    public static final int COUNT = 0xC0;

    /**
     * Represents the OBEX Name header. This specifies the name of the object.
     * <P>
     * The value of <code>NAME</code> is 0x01 (1).
     */
    public static final int NAME = 0x01;

    /**
     * Represents the OBEX Type header. This allows a request to specify the
     * type of the object (e.g. text, html, binary, etc.).
     * <P>
     * The value of <code>TYPE</code> is 0x42 (66).
     */
    public static final int TYPE = 0x42;

    /**
     * Represents the OBEX Length header. This is the length of the object in
     * bytes.
     * <P>
     * The value of <code>LENGTH</code> is 0xC3 (195).
     */
    public static final int LENGTH = 0xC3;

    /**
     * Represents the OBEX Time header using the ISO 8601 standards. This is the
     * preferred time header.
     * <P>
     * The value of <code>TIME_ISO_8601</code> is 0x44 (68).
     */
    public static final int TIME_ISO_8601 = 0x44;

    /**
     * Represents the OBEX Time header using the 4 byte representation. This is
     * only included for backwards compatibility. It represents the number of
     * seconds since January 1, 1970.
     * <P>
     * The value of <code>TIME_4_BYTE</code> is 0xC4 (196).
     */
    public static final int TIME_4_BYTE = 0xC4;

    /**
     * Represents the OBEX Description header. This is a text description of the
     * object.
     * <P>
     * The value of <code>DESCRIPTION</code> is 0x05 (5).
     */
    public static final int DESCRIPTION = 0x05;

    /**
     * Represents the OBEX Target header. This is the name of the service an
     * operation is targeted to.
     * <P>
     * The value of <code>TARGET</code> is 0x46 (70).
     */
    public static final int TARGET = 0x46;

    /**
     * Represents the OBEX HTTP header. This allows an HTTP 1.X header to be
     * included in a request or reply.
     * <P>
     * The value of <code>HTTP</code> is 0x47 (71).
     */
    public static final int HTTP = 0x47;

    /**
     * Represents the OBEX BODY header.
     * <P>
     * The value of <code>BODY</code> is 0x48 (72).
     */
    public static final int BODY = 0x48;

    /**
     * Represents the OBEX End of BODY header.
     * <P>
     * The value of <code>BODY</code> is 0x49 (73).
     */
    public static final int END_OF_BODY = 0x49;

    /**
     * Represents the OBEX Who header. Identifies the OBEX application to
     * determine if the two peers are talking to each other.
     * <P>
     * The value of <code>WHO</code> is 0x4A (74).
     */
    public static final int WHO = 0x4A;

    /**
     * Represents the OBEX Connection ID header. Identifies used for OBEX
     * connection multiplexing.
     * <P>
     * The value of <code>CONNECTION_ID</code> is 0xCB (203).
     */

    public static final int CONNECTION_ID = 0xCB;

    /**
     * Represents the OBEX Application Parameter header. This header specifies
     * additional application request and response information.
     * <P>
     * The value of <code>APPLICATION_PARAMETER</code> is 0x4C (76).
     */
    public static final int APPLICATION_PARAMETER = 0x4C;

    /**
     * Represents the OBEX authentication digest-challenge.
     * <P>
     * The value of <code>AUTH_CHALLENGE</code> is 0x4D (77).
     */
    public static final int AUTH_CHALLENGE = 0x4D;

    /**
     * Represents the OBEX authentication digest-response.
     * <P>
     * The value of <code>AUTH_RESPONSE</code> is 0x4E (78).
     */
    public static final int AUTH_RESPONSE = 0x4E;

    /**
     * Represents the OBEX Object Class header. This header specifies the OBEX
     * object class of the object.
     * <P>
     * The value of <code>OBJECT_CLASS</code> is 0x4F (79).
     */
    public static final int OBJECT_CLASS = 0x4F;

    /**
     * Represents the OBEX Single Response Mode (SRM). This header is used
     * for Single response mode, introduced in OBEX 1.5.
     * <P>
     * The value of <code>SINGLE_RESPONSE_MODE</code> is 0x97 (151).
     */
    public static final int SINGLE_RESPONSE_MODE = 0x97;

    /**
     * Represents the OBEX Single Response Mode Parameters. This header is used
     * for Single response mode, introduced in OBEX 1.5.
     * <P>
     * The value of <code>SINGLE_RESPONSE_MODE_PARAMETER</code> is 0x98 (152).
     */
    public static final int SINGLE_RESPONSE_MODE_PARAMETER = 0x98;

    private Long mCount; // 4 byte unsigned integer

    private String mName; // null terminated Unicode text string

    private boolean mEmptyName;

    private String mType; // null terminated ASCII text string

    private Long mLength; // 4 byte unsigend integer

    private Calendar mIsoTime; // String of the form YYYYMMDDTHHMMSSZ

    private Calendar mByteTime; // 4 byte unsigned integer

    private String mDescription; // null terminated Unicode text String

    private byte[] mTarget; // byte sequence

    private byte[] mHttpHeader; // byte sequence

    private byte[] mWho; // length prefixed byte sequence

    private byte[] mAppParam; // byte sequence of the form tag length value

    private byte[] mObjectClass; // byte sequence

    private String[] mUnicodeUserDefined; // null terminated unicode string

    private byte[][] mSequenceUserDefined; // byte sequence user defined

    private Byte[] mByteUserDefined; // 1 byte

    private Long[] mIntegerUserDefined; // 4 byte unsigned integer

    private SecureRandom mRandom = null;

    private Byte mSingleResponseMode; // byte to indicate enable/disable/support for SRM

    private Byte mSrmParam; // byte representing the SRM parameters - only "wait"
                            // is supported by Bluetooth

    /*package*/ byte[] nonce;

    public byte[] mAuthChall; // The authentication challenge header

    public byte[] mAuthResp; // The authentication response header

    public byte[] mConnectionID; // THe connection ID

    public int responseCode;

    /**
     * Creates new <code>HeaderSet</code> object.
     * @param size the max packet size for this connection
     */
    public HeaderSet() {
        mUnicodeUserDefined = new String[16];
        mSequenceUserDefined = new byte[16][];
        mByteUserDefined = new Byte[16];
        mIntegerUserDefined = new Long[16];
        responseCode = -1;
    }

    /**
     * Sets flag for special "value" of NAME header which should be empty. This
     * is not the same as NAME header with empty string in which case it will
     * have length of 5 bytes. It should be 3 bytes with only header id and
     * length field.
     */
    public void setEmptyNameHeader() {
        mName = null;
        mEmptyName = true;
    }

    /**
     * Gets flag for special "value" of NAME header which should be empty. See
     * above.
     */
    public boolean getEmptyNameHeader() {
        return mEmptyName;
    }

    /**
     * Sets the value of the header identifier to the value provided. The type
     * of object must correspond to the Java type defined in the description of
     * this interface. If <code>null</code> is passed as the
     * <code>headerValue</code> then the header will be removed from the set of
     * headers to include in the next request.
     * @param headerID the identifier to include in the message
     * @param headerValue the value of the header identifier
     * @throws IllegalArgumentException if the header identifier provided is not
     *         one defined in this interface or a user-defined header; if the
     *         type of <code>headerValue</code> is not the correct Java type as
     *         defined in the description of this interface\
     */
    public void setHeader(int headerID, Object headerValue) {
        long temp = -1;

        switch (headerID) {
            case COUNT:
                if (!(headerValue instanceof Long)) {
                    if (headerValue == null) {
                        mCount = null;
                        break;
                    }
                    throw new IllegalArgumentException("Count must be a Long");
                }
                temp = ((Long)headerValue).longValue();
                if ((temp < 0L) || (temp > 0xFFFFFFFFL)) {
                    throw new IllegalArgumentException("Count must be between 0 and 0xFFFFFFFF");
                }
                mCount = (Long)headerValue;
                break;
            case NAME:
                if ((headerValue != null) && (!(headerValue instanceof String))) {
                    throw new IllegalArgumentException("Name must be a String");
                }
                mEmptyName = false;
                mName = (String)headerValue;
                break;
            case TYPE:
                if ((headerValue != null) && (!(headerValue instanceof String))) {
                    throw new IllegalArgumentException("Type must be a String");
                }
                mType = (String)headerValue;
                break;
            case LENGTH:
                if (!(headerValue instanceof Long)) {
                    if (headerValue == null) {
                        mLength = null;
                        break;
                    }
                    throw new IllegalArgumentException("Length must be a Long");
                }
                temp = ((Long)headerValue).longValue();
                if ((temp < 0L) || (temp > 0xFFFFFFFFL)) {
                    throw new IllegalArgumentException("Length must be between 0 and 0xFFFFFFFF");
                }
                mLength = (Long)headerValue;
                break;
            case TIME_ISO_8601:
                if ((headerValue != null) && (!(headerValue instanceof Calendar))) {
                    throw new IllegalArgumentException("Time ISO 8601 must be a Calendar");
                }
                mIsoTime = (Calendar)headerValue;
                break;
            case TIME_4_BYTE:
                if ((headerValue != null) && (!(headerValue instanceof Calendar))) {
                    throw new IllegalArgumentException("Time 4 Byte must be a Calendar");
                }
                mByteTime = (Calendar)headerValue;
                break;
            case DESCRIPTION:
                if ((headerValue != null) && (!(headerValue instanceof String))) {
                    throw new IllegalArgumentException("Description must be a String");
                }
                mDescription = (String)headerValue;
                break;
            case TARGET:
                if (headerValue == null) {
                    mTarget = null;
                } else {
                    if (!(headerValue instanceof byte[])) {
                        throw new IllegalArgumentException("Target must be a byte array");
                    } else {
                        mTarget = new byte[((byte[])headerValue).length];
                        System.arraycopy(headerValue, 0, mTarget, 0, mTarget.length);
                    }
                }
                break;
            case HTTP:
                if (headerValue == null) {
                    mHttpHeader = null;
                } else {
                    if (!(headerValue instanceof byte[])) {
                        throw new IllegalArgumentException("HTTP must be a byte array");
                    } else {
                        mHttpHeader = new byte[((byte[])headerValue).length];
                        System.arraycopy(headerValue, 0, mHttpHeader, 0, mHttpHeader.length);
                    }
                }
                break;
            case WHO:
                if (headerValue == null) {
                    mWho = null;
                } else {
                    if (!(headerValue instanceof byte[])) {
                        throw new IllegalArgumentException("WHO must be a byte array");
                    } else {
                        mWho = new byte[((byte[])headerValue).length];
                        System.arraycopy(headerValue, 0, mWho, 0, mWho.length);
                    }
                }
                break;
            case OBJECT_CLASS:
                if (headerValue == null) {
                    mObjectClass = null;
                } else {
                    if (!(headerValue instanceof byte[])) {
                        throw new IllegalArgumentException("Object Class must be a byte array");
                    } else {
                        mObjectClass = new byte[((byte[])headerValue).length];
                        System.arraycopy(headerValue, 0, mObjectClass, 0, mObjectClass.length);
                    }
                }
                break;
            case APPLICATION_PARAMETER:
                if (headerValue == null) {
                    mAppParam = null;
                } else {
                    if (!(headerValue instanceof byte[])) {
                        throw new IllegalArgumentException(
                                "Application Parameter must be a byte array");
                    } else {
                        mAppParam = new byte[((byte[])headerValue).length];
                        System.arraycopy(headerValue, 0, mAppParam, 0, mAppParam.length);
                    }
                }
                break;
            case SINGLE_RESPONSE_MODE:
                if (headerValue == null) {
                    mSingleResponseMode = null;
                } else {
                    if (!(headerValue instanceof Byte)) {
                        throw new IllegalArgumentException(
                                "Single Response Mode must be a Byte");
                    } else {
                        mSingleResponseMode = (Byte)headerValue;
                    }
                }
                break;
            case SINGLE_RESPONSE_MODE_PARAMETER:
                if (headerValue == null) {
                    mSrmParam = null;
                } else {
                    if (!(headerValue instanceof Byte)) {
                        throw new IllegalArgumentException(
                                "Single Response Mode Parameter must be a Byte");
                    } else {
                        mSrmParam = (Byte)headerValue;
                    }
                }
                break;
            default:
                // Verify that it was not a Unicode String user Defined
                if ((headerID >= 0x30) && (headerID <= 0x3F)) {
                    if ((headerValue != null) && (!(headerValue instanceof String))) {
                        throw new IllegalArgumentException(
                                "Unicode String User Defined must be a String");
                    }
                    mUnicodeUserDefined[headerID - 0x30] = (String)headerValue;

                    break;
                }
                // Verify that it was not a byte sequence user defined value
                if ((headerID >= 0x70) && (headerID <= 0x7F)) {

                    if (headerValue == null) {
                        mSequenceUserDefined[headerID - 0x70] = null;
                    } else {
                        if (!(headerValue instanceof byte[])) {
                            throw new IllegalArgumentException(
                                    "Byte Sequence User Defined must be a byte array");
                        } else {
                            mSequenceUserDefined[headerID - 0x70] = new byte[((byte[])headerValue).length];
                            System.arraycopy(headerValue, 0, mSequenceUserDefined[headerID - 0x70],
                                    0, mSequenceUserDefined[headerID - 0x70].length);
                        }
                    }
                    break;
                }
                // Verify that it was not a Byte user Defined
                if ((headerID >= 0xB0) && (headerID <= 0xBF)) {
                    if ((headerValue != null) && (!(headerValue instanceof Byte))) {
                        throw new IllegalArgumentException("ByteUser Defined must be a Byte");
                    }
                    mByteUserDefined[headerID - 0xB0] = (Byte)headerValue;

                    break;
                }
                // Verify that is was not the 4 byte unsigned integer user
                // defined header
                if ((headerID >= 0xF0) && (headerID <= 0xFF)) {
                    if (!(headerValue instanceof Long)) {
                        if (headerValue == null) {
                            mIntegerUserDefined[headerID - 0xF0] = null;
                            break;
                        }
                        throw new IllegalArgumentException("Integer User Defined must be a Long");
                    }
                    temp = ((Long)headerValue).longValue();
                    if ((temp < 0L) || (temp > 0xFFFFFFFFL)) {
                        throw new IllegalArgumentException(
                                "Integer User Defined must be between 0 and 0xFFFFFFFF");
                    }
                    mIntegerUserDefined[headerID - 0xF0] = (Long)headerValue;
                    break;
                }
                throw new IllegalArgumentException("Invalid Header Identifier");
        }
    }

    /**
     * Retrieves the value of the header identifier provided. The type of the
     * Object returned is defined in the description of this interface.
     * @param headerID the header identifier whose value is to be returned
     * @return the value of the header provided or <code>null</code> if the
     *         header identifier specified is not part of this
     *         <code>HeaderSet</code> object
     * @throws IllegalArgumentException if the <code>headerID</code> is not one
     *         defined in this interface or any of the user-defined headers
     * @throws IOException if an error occurred in the transport layer during
     *         the operation or if the connection has been closed
     */
    public Object getHeader(int headerID) throws IOException {

        switch (headerID) {
            case COUNT:
                return mCount;
            case NAME:
                return mName;
            case TYPE:
                return mType;
            case LENGTH:
                return mLength;
            case TIME_ISO_8601:
                return mIsoTime;
            case TIME_4_BYTE:
                return mByteTime;
            case DESCRIPTION:
                return mDescription;
            case TARGET:
                return mTarget;
            case HTTP:
                return mHttpHeader;
            case WHO:
                return mWho;
            case CONNECTION_ID:
                return mConnectionID;
            case OBJECT_CLASS:
                return mObjectClass;
            case APPLICATION_PARAMETER:
                return mAppParam;
            case SINGLE_RESPONSE_MODE:
                return mSingleResponseMode;
            case SINGLE_RESPONSE_MODE_PARAMETER:
                return mSrmParam;
            default:
                // Verify that it was not a Unicode String user Defined
                if ((headerID >= 0x30) && (headerID <= 0x3F)) {
                    return mUnicodeUserDefined[headerID - 0x30];
                }
                // Verify that it was not a byte sequence user defined header
                if ((headerID >= 0x70) && (headerID <= 0x7F)) {
                    return mSequenceUserDefined[headerID - 0x70];
                }
                // Verify that it was not a byte user defined header
                if ((headerID >= 0xB0) && (headerID <= 0xBF)) {
                    return mByteUserDefined[headerID - 0xB0];
                }
                // Verify that it was not a integer user defined header
                if ((headerID >= 0xF0) && (headerID <= 0xFF)) {
                    return mIntegerUserDefined[headerID - 0xF0];
                }
                throw new IllegalArgumentException("Invalid Header Identifier");
        }
    }

    /**
     * Retrieves the list of headers that may be retrieved via the
     * <code>getHeader</code> method that will not return <code>null</code>. In
     * other words, this method returns all the headers that are available in
     * this object.
     * @see #getHeader
     * @return the array of headers that are set in this object or
     *         <code>null</code> if no headers are available
     * @throws IOException if an error occurred in the transport layer during
     *         the operation or the connection has been closed
     */
    public int[] getHeaderList() throws IOException {
        ByteArrayOutputStream out = new ByteArrayOutputStream();

        if (mCount != null) {
            out.write(COUNT);
        }
        if (mName != null) {
            out.write(NAME);
        }
        if (mType != null) {
            out.write(TYPE);
        }
        if (mLength != null) {
            out.write(LENGTH);
        }
        if (mIsoTime != null) {
            out.write(TIME_ISO_8601);
        }
        if (mByteTime != null) {
            out.write(TIME_4_BYTE);
        }
        if (mDescription != null) {
            out.write(DESCRIPTION);
        }
        if (mTarget != null) {
            out.write(TARGET);
        }
        if (mHttpHeader != null) {
            out.write(HTTP);
        }
        if (mWho != null) {
            out.write(WHO);
        }
        if (mAppParam != null) {
            out.write(APPLICATION_PARAMETER);
        }
        if (mObjectClass != null) {
            out.write(OBJECT_CLASS);
        }
        if(mSingleResponseMode != null) {
            out.write(SINGLE_RESPONSE_MODE);
        }
        if(mSrmParam != null) {
            out.write(SINGLE_RESPONSE_MODE_PARAMETER);
        }

        for (int i = 0x30; i < 0x40; i++) {
            if (mUnicodeUserDefined[i - 0x30] != null) {
                out.write(i);
            }
        }

        for (int i = 0x70; i < 0x80; i++) {
            if (mSequenceUserDefined[i - 0x70] != null) {
                out.write(i);
            }
        }

        for (int i = 0xB0; i < 0xC0; i++) {
            if (mByteUserDefined[i - 0xB0] != null) {
                out.write(i);
            }
        }

        for (int i = 0xF0; i < 0x100; i++) {
            if (mIntegerUserDefined[i - 0xF0] != null) {
                out.write(i);
            }
        }

        byte[] headers = out.toByteArray();
        out.close();

        if ((headers == null) || (headers.length == 0)) {
            return null;
        }

        int[] result = new int[headers.length];
        for (int i = 0; i < headers.length; i++) {
            // Convert the byte to a positive integer.  That is, an integer
            // between 0 and 256.
            result[i] = headers[i] & 0xFF;
        }

        return result;
    }

    /**
     * Sets the authentication challenge header. The <code>realm</code> will be
     * encoded based upon the default encoding scheme used by the implementation
     * to encode strings. Therefore, the encoding scheme used to encode the
     * <code>realm</code> is application dependent.
     * @param realm a short description that describes what password to use; if
     *        <code>null</code> no realm will be sent in the authentication
     *        challenge header
     * @param userID if <code>true</code>, a user ID is required in the reply;
     *        if <code>false</code>, no user ID is required
     * @param access if <code>true</code> then full access will be granted if
     *        successful; if <code>false</code> then read-only access will be
     *        granted if successful
     * @throws IOException
     */
    public void createAuthenticationChallenge(String realm, boolean userID, boolean access)
            throws IOException {

        nonce = new byte[16];
        if(mRandom == null) {
            mRandom = new SecureRandom();
        }
        for (int i = 0; i < 16; i++) {
            nonce[i] = (byte)mRandom.nextInt();
        }

        mAuthChall = ObexHelper.computeAuthenticationChallenge(nonce, realm, access, userID);
    }

    /**
     * Returns the response code received from the server. Response codes are
     * defined in the <code>ResponseCodes</code> class.
     * @see ResponseCodes
     * @return the response code retrieved from the server
     * @throws IOException if an error occurred in the transport layer during
     *         the transaction; if this method is called on a
     *         <code>HeaderSet</code> object created by calling
     *         <code>createHeaderSet()</code> in a <code>ClientSession</code>
     *         object; if this object was created by an OBEX server
     */
    public int getResponseCode() throws IOException {
        if (responseCode == -1) {
            throw new IOException("May not be called on a server");
        } else {
            return responseCode;
        }
    }
}
