/*
 * 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.content.ClipDescription;
import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;

import java.security.InvalidParameterException;

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

    @NonNull
    private final Uri mContentUri;
    @NonNull
    private final ClipDescription mDescription;
    @Nullable
    private final Uri mLinkUri;

    /**
     * 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;
        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 (contentUriScheme == null || !contentUriScheme.equalsIgnoreCase("content")) {
            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() { return mContentUri; }

    /**
     * @return {@link ClipDescription} object that contains the metadata of {@code contentUri} 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; }

    /**
     * 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);
        mDescription.writeToParcel(dest, flags);
        Uri.writeToParcel(dest, mLinkUri);
    }

    private InputContentInfo(@NonNull Parcel source) {
        mContentUri = Uri.CREATOR.createFromParcel(source);
        mDescription = ClipDescription.CREATOR.createFromParcel(source);
        mLinkUri = Uri.CREATOR.createFromParcel(source);
    }

    /**
     * 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;
    }
}
