/*
 * 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.hardware.camera2.marshal.impl;

import android.hardware.camera2.marshal.Marshaler;
import android.hardware.camera2.marshal.MarshalQueryable;
import android.hardware.camera2.utils.TypeReference;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Log;

import java.lang.reflect.Field;
import java.nio.ByteBuffer;

/**
 * Marshal any {@code T extends Parcelable} to/from any native type
 *
 * <p>Use with extreme caution! File descriptors and binders will not be marshaled across.</p>
 */
public class MarshalQueryableParcelable<T extends Parcelable>
        implements MarshalQueryable<T> {

    private static final String TAG = "MarshalParcelable";
    private static final boolean DEBUG = false;

    private static final String FIELD_CREATOR = "CREATOR";

    private class MarshalerParcelable extends Marshaler<T> {

        private final Class<T> mClass;
        private final Parcelable.Creator<T> mCreator;

        @SuppressWarnings("unchecked")
        protected MarshalerParcelable(TypeReference<T> typeReference,
                int nativeType) {
            super(MarshalQueryableParcelable.this, typeReference, nativeType);

            mClass = (Class<T>)typeReference.getRawType();
            Field creatorField;
            try {
                creatorField = mClass.getDeclaredField(FIELD_CREATOR);
            } catch (NoSuchFieldException e) {
                // Impossible. All Parcelable implementations must have a 'CREATOR' static field
                throw new AssertionError(e);
            }

            try {
                mCreator = (Parcelable.Creator<T>)creatorField.get(null);
            } catch (IllegalAccessException e) {
                // Impossible: All 'CREATOR' static fields must be public
                throw new AssertionError(e);
            } catch (IllegalArgumentException e) {
                // Impossible: This is a static field, so null must be ok
                throw new AssertionError(e);
            }
        }

        @Override
        public void marshal(T value, ByteBuffer buffer) {
            if (DEBUG) {
                Log.v(TAG, "marshal " + value);
            }

            Parcel parcel = Parcel.obtain();
            byte[] parcelContents;

            try {
                value.writeToParcel(parcel, /*flags*/0);

                if (parcel.hasFileDescriptors()) {
                    throw new UnsupportedOperationException(
                            "Parcelable " + value + " must not have file descriptors");
                }

                parcelContents = parcel.marshall();
            }
            finally {
                parcel.recycle();
            }

            if (parcelContents.length == 0) {
                throw new AssertionError("No data marshaled for " + value);
            }

            buffer.put(parcelContents);
        }

        @Override
        public T unmarshal(ByteBuffer buffer) {
            if (DEBUG) {
                Log.v(TAG, "unmarshal, buffer remaining " + buffer.remaining());
            }

            /*
             * Quadratically slow when marshaling an array of parcelables.
             *
             * Read out the entire byte buffer as an array, then copy it into the parcel.
             *
             * Once we unparcel the entire object, advance the byte buffer by only how many
             * bytes the parcel actually used up.
             *
             * Future: If we ever do need to use parcelable arrays, we can do this a little smarter
             * by reading out a chunk like 4,8,16,24 each time, but not sure how to detect
             * parcels being too short in this case.
             *
             * Future: Alternatively use Parcel#obtain(long) directly into the native
             * pointer of a ByteBuffer, which would not copy if the ByteBuffer was direct.
             */
            buffer.mark();

            Parcel parcel = Parcel.obtain();
            try {
                int maxLength = buffer.remaining();

                byte[] remaining = new byte[maxLength];
                buffer.get(remaining);

                parcel.unmarshall(remaining, /*offset*/0, maxLength);
                parcel.setDataPosition(/*pos*/0);

                T value = mCreator.createFromParcel(parcel);
                int actualLength = parcel.dataPosition();

                if (actualLength == 0) {
                    throw new AssertionError("No data marshaled for " + value);
                }

                // set the position past the bytes the parcelable actually used
                buffer.reset();
                buffer.position(buffer.position() + actualLength);

                if (DEBUG) {
                    Log.v(TAG, "unmarshal, parcel length was " + actualLength);
                    Log.v(TAG, "unmarshal, value is " + value);
                }

                return mClass.cast(value);
            } finally {
                parcel.recycle();
            }
        }

        @Override
        public int getNativeSize() {
            return NATIVE_SIZE_DYNAMIC;
        }

        @Override
        public int calculateMarshalSize(T value) {
            Parcel parcel = Parcel.obtain();
            try {
                value.writeToParcel(parcel, /*flags*/0);
                int length = parcel.marshall().length;

                if (DEBUG) {
                    Log.v(TAG, "calculateMarshalSize, length when parceling "
                            + value + " is " + length);
                }

                return length;
            } finally {
                parcel.recycle();
            }
        }
    }

    @Override
    public Marshaler<T> createMarshaler(TypeReference<T> managedType, int nativeType) {
        return new MarshalerParcelable(managedType, nativeType);
    }

    @Override
    public boolean isTypeMappingSupported(TypeReference<T> managedType, int nativeType) {
        return Parcelable.class.isAssignableFrom(managedType.getRawType());
    }

}
