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

import android.annotation.NonNull;
import android.os.Build;

import com.android.internal.util.Preconditions;

import dalvik.system.VMRuntime;

/**
 * This class encapsulates information about an object on an MTP device.
 * This corresponds to the ObjectInfo Dataset described in
 * section 5.3.1 of the MTP specification.
 */
public final class MtpObjectInfo {
    private int mHandle;
    private int mStorageId;
    private int mFormat;
    private int mProtectionStatus;
    private int mCompressedSize;
    private int mThumbFormat;
    private int mThumbCompressedSize;
    private int mThumbPixWidth;
    private int mThumbPixHeight;
    private int mImagePixWidth;
    private int mImagePixHeight;
    private int mImagePixDepth;
    private int mParent;
    private int mAssociationType;
    private int mAssociationDesc;
    private int mSequenceNumber;
    private String mName = "";
    private long mDateCreated;
    private long mDateModified;
    private String mKeywords = "";

    // only instantiated via JNI or via a builder
    private MtpObjectInfo() {
    }

    /**
     * Returns the object handle for the MTP object
     *
     * @return the object handle
     */
    public final int getObjectHandle() {
        return mHandle;
    }

    /**
     * Returns the storage ID for the MTP object's storage unit
     *
     * @return the storage ID
     */
    public final int getStorageId() {
        return mStorageId;
    }

    /**
     * Returns the format code for the MTP object
     *
     * @return the format code
     */
    public final int getFormat() {
        return mFormat;
    }

    /**
     * Returns the protection status for the MTP object
     * Possible values are:
     *
     * <ul>
     * <li> {@link android.mtp.MtpConstants#PROTECTION_STATUS_NONE}
     * <li> {@link android.mtp.MtpConstants#PROTECTION_STATUS_READ_ONLY}
     * <li> {@link android.mtp.MtpConstants#PROTECTION_STATUS_NON_TRANSFERABLE_DATA}
     * </ul>
     *
     * @return the protection status
     */
    public final int getProtectionStatus() {
        return mProtectionStatus;
    }

    /**
     * Returns the size of the MTP object
     *
     * @return the object size
     */
    public final int getCompressedSize() {
        Preconditions.checkState(mCompressedSize >= 0);
        return mCompressedSize;
    }

    /**
     * Returns the size of the MTP object
     *
     * @return the object size
     */
    public final long getCompressedSizeLong() {
        return uint32ToLong(mCompressedSize);
    }

    /**
     * Returns the format code for the MTP object's thumbnail
     * Will be zero for objects with no thumbnail
     *
     * @return the thumbnail format code
     */
    public final int getThumbFormat() {
        return mThumbFormat;
    }

    /**
     * Returns the size of the MTP object's thumbnail
     * Will be zero for objects with no thumbnail
     *
     * @return the thumbnail size
     */
    public final int getThumbCompressedSize() {
        Preconditions.checkState(mThumbCompressedSize >= 0);
        return mThumbCompressedSize;
    }

    /**
     * Returns the size of the MTP object's thumbnail
     * Will be zero for objects with no thumbnail
     *
     * @return the thumbnail size
     */
    public final long getThumbCompressedSizeLong() {
        return uint32ToLong(mThumbCompressedSize);
    }

    /**
     * Returns the width of the MTP object's thumbnail in pixels
     * Will be zero for objects with no thumbnail
     *
     * @return the thumbnail width
     */
    public final int getThumbPixWidth() {
        Preconditions.checkState(mThumbPixWidth >= 0);
        return mThumbPixWidth;
    }

    /**
     * Returns the width of the MTP object's thumbnail in pixels
     * Will be zero for objects with no thumbnail
     *
     * @return the thumbnail width
     */
    public final long getThumbPixWidthLong() {
        return uint32ToLong(mThumbPixWidth);
    }

    /**
     * Returns the height of the MTP object's thumbnail in pixels
     * Will be zero for objects with no thumbnail
     *
     * @return the thumbnail height
     */
    public final int getThumbPixHeight() {
        Preconditions.checkState(mThumbPixHeight >= 0);
        return mThumbPixHeight;
    }

    /**
     * Returns the height of the MTP object's thumbnail in pixels
     * Will be zero for objects with no thumbnail
     *
     * @return the thumbnail height
     */
    public final long getThumbPixHeightLong() {
        return uint32ToLong(mThumbPixHeight);
    }

    /**
     * Returns the width of the MTP object in pixels
     * Will be zero for non-image objects
     *
     * @return the image width
     */
    public final int getImagePixWidth() {
        Preconditions.checkState(mImagePixWidth >= 0);
        return mImagePixWidth;
    }

    /**
     * Returns the width of the MTP object in pixels
     * Will be zero for non-image objects
     *
     * @return the image width
     */
    public final long getImagePixWidthLong() {
        return uint32ToLong(mImagePixWidth);
    }

    /**
     * Returns the height of the MTP object in pixels
     * Will be zero for non-image objects
     *
     * @return the image height
     */
    public final int getImagePixHeight() {
        Preconditions.checkState(mImagePixHeight >= 0);
        return mImagePixHeight;
    }

    /**
     * Returns the height of the MTP object in pixels
     * Will be zero for non-image objects
     *
     * @return the image height
     */
    public final long getImagePixHeightLong() {
        return uint32ToLong(mImagePixHeight);
    }

    /**
     * Returns the depth of the MTP object in bits per pixel
     * Will be zero for non-image objects
     *
     * @return the image depth
     */
    public final int getImagePixDepth() {
        Preconditions.checkState(mImagePixDepth >= 0);
        return mImagePixDepth;
    }

    /**
     * Returns the depth of the MTP object in bits per pixel
     * Will be zero for non-image objects
     *
     * @return the image depth
     */
    public final long getImagePixDepthLong() {
        return uint32ToLong(mImagePixDepth);
    }

    /**
     * Returns the object handle for the object's parent
     * Will be zero for the root directory of a storage unit
     *
     * @return the object's parent
     */
    public final int getParent() {
        return mParent;
    }

    /**
     * Returns the association type for the MTP object
     * Will be zero objects that are not of format
     * {@link android.mtp.MtpConstants#FORMAT_ASSOCIATION}
     * For directories the association type is typically
     * {@link android.mtp.MtpConstants#ASSOCIATION_TYPE_GENERIC_FOLDER}
     *
     * @return the object's association type
     */
    public final int getAssociationType() {
        return mAssociationType;
    }

    /**
     * Returns the association description for the MTP object
     * Will be zero objects that are not of format
     * {@link android.mtp.MtpConstants#FORMAT_ASSOCIATION}
     *
     * @return the object's association description
     */
    public final int getAssociationDesc() {
        return mAssociationDesc;
    }

    /**
     * Returns the sequence number for the MTP object
     * This field is typically not used for MTP devices,
     * but is sometimes used to define a sequence of photos
     * on PTP cameras.
     *
     * @return the object's sequence number
     */
    public final int getSequenceNumber() {
        Preconditions.checkState(mSequenceNumber >= 0);
        return mSequenceNumber;
    }

    /**
     * Returns the sequence number for the MTP object
     * This field is typically not used for MTP devices,
     * but is sometimes used to define a sequence of photos
     * on PTP cameras.
     *
     * @return the object's sequence number
     */
    public final long getSequenceNumberLong() {
        return uint32ToLong(mSequenceNumber);
    }

   /**
     * Returns the name of the MTP object
     *
     * @return the object's name
     */
    public final @NonNull String getName() {
        return mName;
    }

   /**
     * Returns the creation date of the MTP object
     * The value is represented as milliseconds since January 1, 1970
     *
     * @return the object's creation date
     */
    public final long getDateCreated() {
        return mDateCreated;
    }

   /**
     * Returns the modification date of the MTP object
     * The value is represented as milliseconds since January 1, 1970
     *
     * @return the object's modification date
     */
    public final long getDateModified() {
        return mDateModified;
    }

   /**
     * Returns a comma separated list of keywords for the MTP object
     *
     * @return the object's keyword list
     */
    public final @NonNull String getKeywords() {
        return mKeywords;
    }

    /**
     * Builds a new object info instance.
     */
    public static class Builder {
        private MtpObjectInfo mObjectInfo;

        public Builder() {
            mObjectInfo = new MtpObjectInfo();
            mObjectInfo.mHandle = -1;
        }

        /**
         * Creates a builder on a copy of an existing object info.
         * All fields, except the object handle will be copied.
         *
         * @param objectInfo object info of an existing entry
         */
        public Builder(MtpObjectInfo objectInfo) {
            mObjectInfo = new MtpObjectInfo();
            mObjectInfo.mHandle = -1;
            mObjectInfo.mAssociationDesc = objectInfo.mAssociationDesc;
            mObjectInfo.mAssociationType = objectInfo.mAssociationType;
            mObjectInfo.mCompressedSize = objectInfo.mCompressedSize;
            mObjectInfo.mDateCreated = objectInfo.mDateCreated;
            mObjectInfo.mDateModified = objectInfo.mDateModified;
            mObjectInfo.mFormat = objectInfo.mFormat;
            mObjectInfo.mImagePixDepth = objectInfo.mImagePixDepth;
            mObjectInfo.mImagePixHeight = objectInfo.mImagePixHeight;
            mObjectInfo.mImagePixWidth = objectInfo.mImagePixWidth;
            mObjectInfo.mKeywords = objectInfo.mKeywords;
            mObjectInfo.mName = objectInfo.mName;
            mObjectInfo.mParent = objectInfo.mParent;
            mObjectInfo.mProtectionStatus = objectInfo.mProtectionStatus;
            mObjectInfo.mSequenceNumber = objectInfo.mSequenceNumber;
            mObjectInfo.mStorageId = objectInfo.mStorageId;
            mObjectInfo.mThumbCompressedSize = objectInfo.mThumbCompressedSize;
            mObjectInfo.mThumbFormat = objectInfo.mThumbFormat;
            mObjectInfo.mThumbPixHeight = objectInfo.mThumbPixHeight;
            mObjectInfo.mThumbPixWidth = objectInfo.mThumbPixWidth;
        }

        public Builder setObjectHandle(int value) {
            mObjectInfo.mHandle = value;
            return this;
        }

        public Builder setAssociationDesc(int value) {
            mObjectInfo.mAssociationDesc = value;
            return this;
        }

        public Builder setAssociationType(int value) {
            mObjectInfo.mAssociationType = value;
            return this;
        }

        public Builder setCompressedSize(long value) {
            mObjectInfo.mCompressedSize = longToUint32(value, "value");
            return this;
        }

        public Builder setDateCreated(long value) {
            mObjectInfo.mDateCreated = value;
            return this;
        }

        public Builder setDateModified(long value) {
            mObjectInfo.mDateModified = value;
            return this;
        }

        public Builder setFormat(int value) {
            mObjectInfo.mFormat = value;
            return this;
        }

        public Builder setImagePixDepth(long value) {
            mObjectInfo.mImagePixDepth = longToUint32(value, "value");
            return this;
        }

        public Builder setImagePixHeight(long value) {
            mObjectInfo.mImagePixHeight = longToUint32(value, "value");
            return this;
        }

        public Builder setImagePixWidth(long value) {
            mObjectInfo.mImagePixWidth = longToUint32(value, "value");
            return this;
        }

        public Builder setKeywords(@NonNull String value) {
            if (VMRuntime.getRuntime().getTargetSdkVersion() > Build.VERSION_CODES.N_MR1) {
                Preconditions.checkNotNull(value);
            } else if (value == null) {
                // Before N_MR1 we accept null value and it was regarded as an empty string in
                // MtpDevice#sendObjectInfo.
                value = "";
            }
            mObjectInfo.mKeywords = value;
            return this;
        }

        public Builder setName(@NonNull String value) {
            Preconditions.checkNotNull(value);
            mObjectInfo.mName = value;
            return this;
        }

        public Builder setParent(int value) {
            mObjectInfo.mParent = value;
            return this;
        }

        public Builder setProtectionStatus(int value) {
            mObjectInfo.mProtectionStatus = value;
            return this;
        }

        public Builder setSequenceNumber(long value) {
            mObjectInfo.mSequenceNumber = longToUint32(value, "value");
            return this;
        }

        public Builder setStorageId(int value) {
            mObjectInfo.mStorageId = value;
            return this;
        }

        public Builder setThumbCompressedSize(long value) {
            mObjectInfo.mThumbCompressedSize = longToUint32(value, "value");
            return this;
        }

        public Builder setThumbFormat(int value) {
            mObjectInfo.mThumbFormat = value;
            return this;
        }

        public Builder setThumbPixHeight(long value) {
            mObjectInfo.mThumbPixHeight = longToUint32(value, "value");
            return this;
        }

        public Builder setThumbPixWidth(long value) {
            mObjectInfo.mThumbPixWidth = longToUint32(value, "value");
            return this;
        }

        /**
         * Builds the object info instance. Once called, methods of the builder
         * must not be called anymore.
         *
         * @return the object info of the newly created file, or NULL in case
         *         of an error.
         */
        public MtpObjectInfo build() {
            MtpObjectInfo result = mObjectInfo;
            mObjectInfo = null;
            return result;
        }
    }

    private static long uint32ToLong(int value) {
        return value < 0 ? 0x100000000L + value : value;
    }

    private static int longToUint32(long value, String valueName) {
        Preconditions.checkArgumentInRange(value, 0, 0xffffffffL, valueName);
        return (int) value;
    }
}
