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

import android.annotation.IntDef;
import android.annotation.SystemApi;
import android.annotation.TestApi;

import libcore.util.NativeAllocationRegistry;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Arrays;

/** @hide */
@SystemApi
@TestApi
public class HwParcel {
    private static final String TAG = "HwParcel";

    @IntDef(prefix = { "STATUS_" }, value = {
        STATUS_SUCCESS,
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface Status {}

    /**
     * Success return error for a transaction. Written to parcels
     * using writeStatus.
     */
    public static final int STATUS_SUCCESS      = 0;

    private static final NativeAllocationRegistry sNativeRegistry;

    private HwParcel(boolean allocate) {
        native_setup(allocate);

        sNativeRegistry.registerNativeAllocation(
                this,
                mNativeContext);
    }

    /**
     * Creates an initialized and empty parcel.
     */
    public HwParcel() {
        native_setup(true /* allocate */);

        sNativeRegistry.registerNativeAllocation(
                this,
                mNativeContext);
    }

    /**
     * Writes an interface token into the parcel used to verify that
     * a transaction has made it to the write type of interface.
     *
     * @param interfaceName fully qualified name of interface message
     *     is being sent to.
     */
    public native final void writeInterfaceToken(String interfaceName);
    /**
     * Writes a boolean value to the end of the parcel.
     * @param val to write
     */
    public native final void writeBool(boolean val);
    /**
     * Writes a byte value to the end of the parcel.
     * @param val to write
     */
    public native final void writeInt8(byte val);
    /**
     * Writes a short value to the end of the parcel.
     * @param val to write
     */
    public native final void writeInt16(short val);
    /**
     * Writes a int value to the end of the parcel.
     * @param val to write
     */
    public native final void writeInt32(int val);
    /**
     * Writes a long value to the end of the parcel.
     * @param val to write
     */
    public native final void writeInt64(long val);
    /**
     * Writes a float value to the end of the parcel.
     * @param val to write
     */
    public native final void writeFloat(float val);
    /**
     * Writes a double value to the end of the parcel.
     * @param val to write
     */
    public native final void writeDouble(double val);
    /**
     * Writes a String value to the end of the parcel.
     *
     * Note, this will be converted to UTF-8 when it is written.
     *
     * @param val to write
     */
    public native final void writeString(String val);
    /**
     * Writes a native handle (without duplicating the underlying
     * file descriptors) to the end of the parcel.
     *
     * @param val to write
     */
    public native final void writeNativeHandle(NativeHandle val);

    /**
     * Writes an array of boolean values to the end of the parcel.
     * @param val to write
     */
    private native final void writeBoolVector(boolean[] val);
    /**
     * Writes an array of byte values to the end of the parcel.
     * @param val to write
     */
    private native final void writeInt8Vector(byte[] val);
    /**
     * Writes an array of short values to the end of the parcel.
     * @param val to write
     */
    private native final void writeInt16Vector(short[] val);
    /**
     * Writes an array of int values to the end of the parcel.
     * @param val to write
     */
    private native final void writeInt32Vector(int[] val);
    /**
     * Writes an array of long values to the end of the parcel.
     * @param val to write
     */
    private native final void writeInt64Vector(long[] val);
    /**
     * Writes an array of float values to the end of the parcel.
     * @param val to write
     */
    private native final void writeFloatVector(float[] val);
    /**
     * Writes an array of double values to the end of the parcel.
     * @param val to write
     */
    private native final void writeDoubleVector(double[] val);
    /**
     * Writes an array of String values to the end of the parcel.
     *
     * Note, these will be converted to UTF-8 as they are written.
     *
     * @param val to write
     */
    private native final void writeStringVector(String[] val);
    /**
     * Writes an array of native handles to the end of the parcel.
     * @param val array of {@link NativeHandle} objects to write
     */
    private native final void writeNativeHandleVector(NativeHandle[] val);

    /**
     * Helper method to write a list of Booleans to val.
     * @param val list to write
     */
    public final void writeBoolVector(ArrayList<Boolean> val) {
        final int n = val.size();
        boolean[] array = new boolean[n];
        for (int i = 0; i < n; ++i) {
            array[i] = val.get(i);
        }

        writeBoolVector(array);
    }

    /**
     * Helper method to write a list of Booleans to the end of the parcel.
     * @param val list to write
     */
    public final void writeInt8Vector(ArrayList<Byte> val) {
        final int n = val.size();
        byte[] array = new byte[n];
        for (int i = 0; i < n; ++i) {
            array[i] = val.get(i);
        }

        writeInt8Vector(array);
    }

    /**
     * Helper method to write a list of Shorts to the end of the parcel.
     * @param val list to write
     */
    public final void writeInt16Vector(ArrayList<Short> val) {
        final int n = val.size();
        short[] array = new short[n];
        for (int i = 0; i < n; ++i) {
            array[i] = val.get(i);
        }

        writeInt16Vector(array);
    }

    /**
     * Helper method to write a list of Integers to the end of the parcel.
     * @param val list to write
     */
    public final void writeInt32Vector(ArrayList<Integer> val) {
        final int n = val.size();
        int[] array = new int[n];
        for (int i = 0; i < n; ++i) {
            array[i] = val.get(i);
        }

        writeInt32Vector(array);
    }

    /**
     * Helper method to write a list of Longs to the end of the parcel.
     * @param val list to write
     */
    public final void writeInt64Vector(ArrayList<Long> val) {
        final int n = val.size();
        long[] array = new long[n];
        for (int i = 0; i < n; ++i) {
            array[i] = val.get(i);
        }

        writeInt64Vector(array);
    }

    /**
     * Helper method to write a list of Floats to the end of the parcel.
     * @param val list to write
     */
    public final void writeFloatVector(ArrayList<Float> val) {
        final int n = val.size();
        float[] array = new float[n];
        for (int i = 0; i < n; ++i) {
            array[i] = val.get(i);
        }

        writeFloatVector(array);
    }

    /**
     * Helper method to write a list of Doubles to the end of the parcel.
     * @param val list to write
     */
    public final void writeDoubleVector(ArrayList<Double> val) {
        final int n = val.size();
        double[] array = new double[n];
        for (int i = 0; i < n; ++i) {
            array[i] = val.get(i);
        }

        writeDoubleVector(array);
    }

    /**
     * Helper method to write a list of Strings to the end of the parcel.
     * @param val list to write
     */
    public final void writeStringVector(ArrayList<String> val) {
        writeStringVector(val.toArray(new String[val.size()]));
    }

    /**
     * Helper method to write a list of native handles to the end of the parcel.
     * @param val list of {@link NativeHandle} objects to write
     */
    public final void writeNativeHandleVector(ArrayList<NativeHandle> val) {
        writeNativeHandleVector(val.toArray(new NativeHandle[val.size()]));
    }

    /**
     * Write a hwbinder object to the end of the parcel.
     * @param binder value to write
     */
    public native final void writeStrongBinder(IHwBinder binder);

    /**
     * Checks to make sure that the interface name matches the name written by the parcel
     * sender by writeInterfaceToken
     *
     * @throws SecurityException interface doesn't match
     */
    public native final void enforceInterface(String interfaceName);

    /**
     * Reads a boolean value from the current location in the parcel.
     * @return value parsed from the parcel
     * @throws IllegalArgumentException if the parcel has no more data
     */
    public native final boolean readBool();
    /**
     * Reads a byte value from the current location in the parcel.
     * @return value parsed from the parcel
     * @throws IllegalArgumentException if the parcel has no more data
     */
    public native final byte readInt8();
    /**
     * Reads a short value from the current location in the parcel.
     * @return value parsed from the parcel
     * @throws IllegalArgumentException if the parcel has no more data
     */
    public native final short readInt16();
    /**
     * Reads a int value from the current location in the parcel.
     * @return value parsed from the parcel
     * @throws IllegalArgumentException if the parcel has no more data
     */
    public native final int readInt32();
    /**
     * Reads a long value from the current location in the parcel.
     * @return value parsed from the parcel
     * @throws IllegalArgumentException if the parcel has no more data
     */
    public native final long readInt64();
    /**
     * Reads a float value from the current location in the parcel.
     * @return value parsed from the parcel
     * @throws IllegalArgumentException if the parcel has no more data
     */
    public native final float readFloat();
    /**
     * Reads a double value from the current location in the parcel.
     * @return value parsed from the parcel
     * @throws IllegalArgumentException if the parcel has no more data
     */
    public native final double readDouble();
    /**
     * Reads a String value from the current location in the parcel.
     * @return value parsed from the parcel
     * @throws IllegalArgumentException if the parcel has no more data
     */
    public native final String readString();
    /**
     * Reads a native handle (without duplicating the underlying file
     * descriptors) from the parcel. These file descriptors will only
     * be open for the duration that the binder window is open. If they
     * are needed further, you must call {@link NativeHandle#dup()}.
     *
     * @return a {@link NativeHandle} instance parsed from the parcel
     * @throws IllegalArgumentException if the parcel has no more data
     */
    public native final NativeHandle readNativeHandle();
    /**
     * Reads an embedded native handle (without duplicating the underlying
     * file descriptors) from the parcel. These file descriptors will only
     * be open for the duration that the binder window is open. If they
     * are needed further, you must call {@link NativeHandle#dup()}. You
     * do not need to call close on the NativeHandle returned from this.
     *
     * @param parentHandle handle from which to read the embedded object
     * @param offset offset into parent
     * @return a {@link NativeHandle} instance parsed from the parcel
     * @throws IllegalArgumentException if the parcel has no more data
     */
    public native final NativeHandle readEmbeddedNativeHandle(
            long parentHandle, long offset);

    /**
     * Reads an array of boolean values from the parcel.
     * @return array of parsed values
     * @throws IllegalArgumentException if the parcel has no more data
     */
    private native final boolean[] readBoolVectorAsArray();
    /**
     * Reads an array of byte values from the parcel.
     * @return array of parsed values
     * @throws IllegalArgumentException if the parcel has no more data
     */
    private native final byte[] readInt8VectorAsArray();
    /**
     * Reads an array of short values from the parcel.
     * @return array of parsed values
     * @throws IllegalArgumentException if the parcel has no more data
     */
    private native final short[] readInt16VectorAsArray();
    /**
     * Reads an array of int values from the parcel.
     * @return array of parsed values
     * @throws IllegalArgumentException if the parcel has no more data
     */
    private native final int[] readInt32VectorAsArray();
    /**
     * Reads an array of long values from the parcel.
     * @return array of parsed values
     * @throws IllegalArgumentException if the parcel has no more data
     */
    private native final long[] readInt64VectorAsArray();
    /**
     * Reads an array of float values from the parcel.
     * @return array of parsed values
     * @throws IllegalArgumentException if the parcel has no more data
     */
    private native final float[] readFloatVectorAsArray();
    /**
     * Reads an array of double values from the parcel.
     * @return array of parsed values
     * @throws IllegalArgumentException if the parcel has no more data
     */
    private native final double[] readDoubleVectorAsArray();
    /**
     * Reads an array of String values from the parcel.
     * @return array of parsed values
     * @throws IllegalArgumentException if the parcel has no more data
     */
    private native final String[] readStringVectorAsArray();
    /**
     * Reads an array of native handles from the parcel.
     * @return array of {@link NativeHandle} objects
     * @throws IllegalArgumentException if the parcel has no more data
     */
    private native final NativeHandle[] readNativeHandleAsArray();

    /**
     * Convenience method to read a Boolean vector as an ArrayList.
     * @return array of parsed values.
     * @throws IllegalArgumentException if the parcel has no more data
     */
    public final ArrayList<Boolean> readBoolVector() {
        Boolean[] array = HwBlob.wrapArray(readBoolVectorAsArray());

        return new ArrayList<Boolean>(Arrays.asList(array));
    }

    /**
     * Convenience method to read a Byte vector as an ArrayList.
     * @return array of parsed values.
     * @throws IllegalArgumentException if the parcel has no more data
     */
    public final ArrayList<Byte> readInt8Vector() {
        Byte[] array = HwBlob.wrapArray(readInt8VectorAsArray());

        return new ArrayList<Byte>(Arrays.asList(array));
    }

    /**
     * Convenience method to read a Short vector as an ArrayList.
     * @return array of parsed values.
     * @throws IllegalArgumentException if the parcel has no more data
     */
    public final ArrayList<Short> readInt16Vector() {
        Short[] array = HwBlob.wrapArray(readInt16VectorAsArray());

        return new ArrayList<Short>(Arrays.asList(array));
    }

    /**
     * Convenience method to read a Integer vector as an ArrayList.
     * @return array of parsed values.
     * @throws IllegalArgumentException if the parcel has no more data
     */
    public final ArrayList<Integer> readInt32Vector() {
        Integer[] array = HwBlob.wrapArray(readInt32VectorAsArray());

        return new ArrayList<Integer>(Arrays.asList(array));
    }

    /**
     * Convenience method to read a Long vector as an ArrayList.
     * @return array of parsed values.
     * @throws IllegalArgumentException if the parcel has no more data
     */
    public final ArrayList<Long> readInt64Vector() {
        Long[] array = HwBlob.wrapArray(readInt64VectorAsArray());

        return new ArrayList<Long>(Arrays.asList(array));
    }

    /**
     * Convenience method to read a Float vector as an ArrayList.
     * @return array of parsed values.
     * @throws IllegalArgumentException if the parcel has no more data
     */
    public final ArrayList<Float> readFloatVector() {
        Float[] array = HwBlob.wrapArray(readFloatVectorAsArray());

        return new ArrayList<Float>(Arrays.asList(array));
    }

    /**
     * Convenience method to read a Double vector as an ArrayList.
     * @return array of parsed values.
     * @throws IllegalArgumentException if the parcel has no more data
     */
    public final ArrayList<Double> readDoubleVector() {
        Double[] array = HwBlob.wrapArray(readDoubleVectorAsArray());

        return new ArrayList<Double>(Arrays.asList(array));
    }

    /**
     * Convenience method to read a String vector as an ArrayList.
     * @return array of parsed values.
     * @throws IllegalArgumentException if the parcel has no more data
     */
    public final ArrayList<String> readStringVector() {
        return new ArrayList<String>(Arrays.asList(readStringVectorAsArray()));
    }

    /**
     * Convenience method to read a vector of native handles as an ArrayList.
     * @return array of {@link NativeHandle} objects.
     * @throws IllegalArgumentException if the parcel has no more data
     */
    public final ArrayList<NativeHandle> readNativeHandleVector() {
        return new ArrayList<NativeHandle>(Arrays.asList(readNativeHandleAsArray()));
    }

    /**
     * Reads a strong binder value from the parcel.
     * @return binder object read from parcel or null if no binder can be read
     * @throws IllegalArgumentException if the parcel has no more data
     */
    public native final IHwBinder readStrongBinder();

    /**
     * Read opaque segment of data as a blob.
     * @return blob of size expectedSize
     * @throws IllegalArgumentException if the parcel has no more data
     */
    public native final HwBlob readBuffer(long expectedSize);

    /**
     * Read a buffer written using scatter gather.
     *
     * @param expectedSize size that buffer should be
     * @param parentHandle handle from which to read the embedded buffer
     * @param offset offset into parent
     * @param nullable whether or not to allow for a null return
     * @return blob of data with size expectedSize
     * @throws NoSuchElementException if an embedded buffer is not available to read
     * @throws IllegalArgumentException if expectedSize < 0
     * @throws NullPointerException if the transaction specified the blob to be null
     *    but nullable is false
     */
    public native final HwBlob readEmbeddedBuffer(
            long expectedSize, long parentHandle, long offset,
            boolean nullable);

    /**
     * Write a buffer into the transaction.
     * @param blob blob to write into the parcel.
     */
    public native final void writeBuffer(HwBlob blob);
    /**
     * Write a status value into the blob.
     * @param status value to write
     */
    public native final void writeStatus(int status);
    /**
     * @throws IllegalArgumentException if a success vaue cannot be read
     * @throws RemoteException if success value indicates a transaction error
     */
    public native final void verifySuccess();
    /**
     * Should be called to reduce memory pressure when this object no longer needs
     * to be written to.
     */
    public native final void releaseTemporaryStorage();
    /**
     * Should be called when object is no longer needed to reduce possible memory
     * pressure if the Java GC does not get to this object in time.
     */
    public native final void release();

    /**
     * Sends the parcel to the specified destination.
     */
    public native final void send();

    // Returns address of the "freeFunction".
    private static native final long native_init();

    private native final void native_setup(boolean allocate);

    static {
        long freeFunction = native_init();

        sNativeRegistry = new NativeAllocationRegistry(
                HwParcel.class.getClassLoader(),
                freeFunction,
                128 /* size */);
    }

    private long mNativeContext;
}

