/*
 * 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.view.inputmethod;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.content.ClipDescription;
import android.content.ContentProvider;
import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.RemoteException;
import android.os.UserHandle;

import com.android.internal.inputmethod.IInputContentUriToken;

import java.security.InvalidParameterException;

/**
 * A container object with which input methods can send content files to the target application.
 */
public final class InputContentInfo implements Parcelable {

    /**
     * The content URI that may or may not have a user ID embedded by
     * {@link ContentProvider#maybeAddUserId(Uri, int)}.  This always preserves the exact value
     * specified to a constructor.  In other words, if it had user ID embedded when it was passed
     * to the constructor, it still has the same user ID no matter if it is valid or not.
     */
    @NonNull
    private final Uri mContentUri;
    /**
     * The user ID to which {@link #mContentUri} belongs to.  If {@link #mContentUri} already
     * embedded the user ID when it was specified then this fields has the same user ID.  Otherwise
     * the user ID is determined based on the process ID when the constructor is called.
     *
     * <p>CAUTION: If you received {@link InputContentInfo} from a different process, there is no
     * guarantee that this value is correct and valid.  Never use this for any security purpose</p>
     */
    @UserIdInt
    private final int mContentUriOwnerUserId;
    @NonNull
    private final ClipDescription mDescription;
    @Nullable
    private final Uri mLinkUri;
    @NonNull
    private IInputContentUriToken mUriToken;

    /**
     * Constructs {@link InputContentInfo} object only with mandatory data.
     *
     * @param contentUri Content URI to be exported from the input method.
     * This cannot be {@code null}.
     * @param description A {@link ClipDescription} object that contains the metadata of
     * {@code contentUri} such as MIME type(s). This object cannot be {@code null}. Also
     * {@link ClipDescription#getLabel()} should be describing the content specified by
     * {@code contentUri} for accessibility reasons.
     */
    public InputContentInfo(@NonNull Uri contentUri, @NonNull ClipDescription description) {
        this(contentUri, description, null /* link Uri */);
    }

    /**
     * Constructs {@link InputContentInfo} object with additional link URI.
     *
     * @param contentUri Content URI to be exported from the input method.
     * This cannot be {@code null}.
     * @param description A {@link ClipDescription} object that contains the metadata of
     * {@code contentUri} such as MIME type(s). This object cannot be {@code null}. Also
     * {@link ClipDescription#getLabel()} should be describing the content specified by
     * {@code contentUri} for accessibility reasons.
     * @param linkUri An optional {@code http} or {@code https} URI. The editor author may provide
     * a way to navigate the user to the specified web page if this is not {@code null}.
     * @throws InvalidParameterException if any invalid parameter is specified.
     */
    public InputContentInfo(@NonNull Uri contentUri, @NonNull ClipDescription description,
            @Nullable Uri linkUri) {
        validateInternal(contentUri, description, linkUri, true /* throwException */);
        mContentUri = contentUri;
        mContentUriOwnerUserId =
                ContentProvider.getUserIdFromUri(mContentUri, UserHandle.myUserId());
        mDescription = description;
        mLinkUri = linkUri;
    }

    /**
     * @return {@code true} if all the fields are valid.
     * @hide
     */
    public boolean validate() {
        return validateInternal(mContentUri, mDescription, mLinkUri, false /* throwException */);
    }

    /**
     * Constructs {@link InputContentInfo} object with additional link URI.
     *
     * @param contentUri Content URI to be exported from the input method.
     * This cannot be {@code null}.
     * @param description A {@link ClipDescription} object that contains the metadata of
     * {@code contentUri} such as MIME type(s). This object cannot be {@code null}. Also
     * {@link ClipDescription#getLabel()} should be describing the content specified by
     * {@code contentUri} for accessibility reasons.
     * @param linkUri An optional {@code http} or {@code https} URI. The editor author may provide
     * a way to navigate the user to the specified web page if this is not {@code null}.
     * @param throwException {@code true} if this method should throw an
     * {@link InvalidParameterException}.
     * @throws InvalidParameterException if any invalid parameter is specified.
     */
    private static boolean validateInternal(@NonNull Uri contentUri,
            @NonNull ClipDescription description, @Nullable Uri linkUri, boolean throwException) {
        if (contentUri == null) {
            if (throwException) {
                throw new NullPointerException("contentUri");
            }
            return false;
        }
        if (description == null) {
            if (throwException) {
                throw new NullPointerException("description");
            }
            return false;
        }
        final String contentUriScheme = contentUri.getScheme();
        if (!"content".equals(contentUriScheme)) {
            if (throwException) {
                throw new InvalidParameterException("contentUri must have content scheme");
            }
            return false;
        }
        if (linkUri != null) {
            final String scheme = linkUri.getScheme();
            if (scheme == null ||
                    (!scheme.equalsIgnoreCase("http") && !scheme.equalsIgnoreCase("https"))) {
                if (throwException) {
                    throw new InvalidParameterException(
                            "linkUri must have either http or https scheme");
                }
                return false;
            }
        }
        return true;
    }

    /**
     * @return Content URI with which the content can be obtained.
     */
    @NonNull
    public Uri getContentUri() {
        // Fix up the content URI when and only when the caller's user ID does not match the owner's
        // user ID.
        if (mContentUriOwnerUserId != UserHandle.myUserId()) {
            return ContentProvider.maybeAddUserId(mContentUri, mContentUriOwnerUserId);
        }
        return mContentUri;
    }

    /**
     * @return {@link ClipDescription} object that contains the metadata of {@code #getContentUri()}
     * such as MIME type(s). {@link ClipDescription#getLabel()} can be used for accessibility
     * purpose.
     */
    @NonNull
    public ClipDescription getDescription() { return mDescription; }

    /**
     * @return An optional {@code http} or {@code https} URI that is related to this content.
     */
    @Nullable
    public Uri getLinkUri() { return mLinkUri; }

    /**
     * Update the internal state of this object to be associated with the given token.
     *
     * <p>TODO(yukawa): Come up with an idea to make {@link InputContentInfo} immutable.</p>
     *
     * @param token special URI token obtained from the system.
     * @hide
     */
    public void setUriToken(IInputContentUriToken token) {
        if (mUriToken != null) {
            throw new IllegalStateException("URI token is already set");
        }
        mUriToken = token;
    }

    /**
     * Requests a temporary read-only access permission for content URI associated with this object.
     *
     * <p>Does nothing if the temporary permission is already granted.</p>
     */
    public void requestPermission() {
        if (mUriToken == null) {
            return;
        }
        try {
            mUriToken.take();
        } catch (RemoteException e) {
            e.rethrowFromSystemServer();
        }
    }

    /**
     * Releases a temporary read-only access permission for content URI associated with this object.
     *
     * <p>Does nothing if the temporary permission is not granted.</p>
     */
    public void releasePermission() {
        if (mUriToken == null) {
            return;
        }
        try {
            mUriToken.release();
        } catch (RemoteException e) {
            e.rethrowFromSystemServer();
        }
    }

    /**
     * Used to package this object into a {@link Parcel}.
     *
     * @param dest The {@link Parcel} to be written.
     * @param flags The flags used for parceling.
     */
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        Uri.writeToParcel(dest, mContentUri);
        dest.writeInt(mContentUriOwnerUserId);
        mDescription.writeToParcel(dest, flags);
        Uri.writeToParcel(dest, mLinkUri);
        if (mUriToken != null) {
            dest.writeInt(1);
            dest.writeStrongBinder(mUriToken.asBinder());
        } else {
            dest.writeInt(0);
        }
    }

    private InputContentInfo(@NonNull Parcel source) {
        mContentUri = Uri.CREATOR.createFromParcel(source);
        mContentUriOwnerUserId = source.readInt();
        mDescription = ClipDescription.CREATOR.createFromParcel(source);
        mLinkUri = Uri.CREATOR.createFromParcel(source);
        if (source.readInt() == 1) {
            mUriToken = IInputContentUriToken.Stub.asInterface(source.readStrongBinder());
        } else {
            mUriToken = null;
        }
    }

    /**
     * Used to make this class parcelable.
     */
    public static final Parcelable.Creator<InputContentInfo> CREATOR
            = new Parcelable.Creator<InputContentInfo>() {
        @Override
        public InputContentInfo createFromParcel(Parcel source) {
            return new InputContentInfo(source);
        }

        @Override
        public InputContentInfo[] newArray(int size) {
            return new InputContentInfo[size];
        }
    };

    /**
     * {@inheritDoc}
     */
    @Override
    public int describeContents() {
        return 0;
    }
}
