/*
 * Copyright (C) 2017 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.app.slice;

import android.annotation.NonNull;
import android.annotation.StringDef;
import android.app.PendingIntent;
import android.app.RemoteInput;
import android.graphics.drawable.Icon;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
import android.util.Pair;
import android.widget.RemoteViews;

import com.android.internal.util.ArrayUtils;

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


/**
 * A SliceItem is a single unit in the tree structure of a {@link Slice}.
 *
 * A SliceItem a piece of content and some hints about what that content
 * means or how it should be displayed. The types of content can be:
 * <li>{@link #FORMAT_SLICE}</li>
 * <li>{@link #FORMAT_TEXT}</li>
 * <li>{@link #FORMAT_IMAGE}</li>
 * <li>{@link #FORMAT_ACTION}</li>
 * <li>{@link #FORMAT_INT}</li>
 * <li>{@link #FORMAT_LONG}</li>
 * <li>{@link #FORMAT_REMOTE_INPUT}</li>
 * <li>{@link #FORMAT_BUNDLE}</li>
 *
 * The hints that a {@link SliceItem} are a set of strings which annotate
 * the content. The hints that are guaranteed to be understood by the system
 * are defined on {@link Slice}.
 */
public final class SliceItem implements Parcelable {

    private static final String TAG = "SliceItem";

    /**
     * @hide
     */
    @StringDef(prefix = { "FORMAT_" }, value = {
            FORMAT_SLICE,
            FORMAT_TEXT,
            FORMAT_IMAGE,
            FORMAT_ACTION,
            FORMAT_INT,
            FORMAT_LONG,
            FORMAT_REMOTE_INPUT,
            FORMAT_BUNDLE,
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface SliceType {}

    /**
     * A {@link SliceItem} that contains a {@link Slice}
     */
    public static final String FORMAT_SLICE = "slice";
    /**
     * A {@link SliceItem} that contains a {@link CharSequence}
     */
    public static final String FORMAT_TEXT = "text";
    /**
     * A {@link SliceItem} that contains an {@link Icon}
     */
    public static final String FORMAT_IMAGE = "image";
    /**
     * A {@link SliceItem} that contains a {@link PendingIntent}
     *
     * Note: Actions contain 2 pieces of data, In addition to the pending intent, the
     * item contains a {@link Slice} that the action applies to.
     */
    public static final String FORMAT_ACTION = "action";
    /**
     * A {@link SliceItem} that contains an int.
     */
    public static final String FORMAT_INT = "int";
    /**
     * A {@link SliceItem} that contains a long.
     */
    public static final String FORMAT_LONG = "long";
    /**
     * @deprecated TO BE REMOVED
     * @removed
     */
    @Deprecated
    public static final String FORMAT_TIMESTAMP = FORMAT_LONG;
    /**
     * A {@link SliceItem} that contains a {@link RemoteInput}.
     */
    public static final String FORMAT_REMOTE_INPUT = "input";
    /**
     * A {@link SliceItem} that contains a {@link Bundle}.
     */
    public static final String FORMAT_BUNDLE = "bundle";

    /**
     * @hide
     */
    protected @Slice.SliceHint
    String[] mHints;
    private final String mFormat;
    private final String mSubType;
    private final Object mObj;

    /**
     * @hide
     */
    public SliceItem(Object obj, @SliceType String format, String subType,
            List<String> hints) {
        this(obj, format, subType, hints.toArray(new String[hints.size()]));
    }

    /**
     * @hide
     */
    public SliceItem(Object obj, @SliceType String format, String subType,
            @Slice.SliceHint String[] hints) {
        mHints = hints;
        mFormat = format;
        mSubType = subType;
        mObj = obj;
    }

    /**
     * @hide
     */
    public SliceItem(PendingIntent intent, Slice slice, String format, String subType,
            @Slice.SliceHint String[] hints) {
        this(new Pair<>(intent, slice), format, subType, hints);
    }

    /**
     * Gets all hints associated with this SliceItem.
     * @return Array of hints.
     */
    public @NonNull @Slice.SliceHint List<String> getHints() {
        return Arrays.asList(mHints);
    }

    /**
     * Get the format of this SliceItem.
     * <p>
     * The format will be one of the following types supported by the platform:
     * <li>{@link #FORMAT_SLICE}</li>
     * <li>{@link #FORMAT_TEXT}</li>
     * <li>{@link #FORMAT_IMAGE}</li>
     * <li>{@link #FORMAT_ACTION}</li>
     * <li>{@link #FORMAT_INT}</li>
     * <li>{@link #FORMAT_LONG}</li>
     * <li>{@link #FORMAT_REMOTE_INPUT}</li>
     * <li>{@link #FORMAT_BUNDLE}</li>
     * @see #getSubType() ()
     */
    public String getFormat() {
        return mFormat;
    }

    /**
     * Get the sub-type of this SliceItem.
     * <p>
     * Subtypes provide additional information about the type of this information beyond basic
     * interpretations inferred by {@link #getFormat()}. For example a slice may contain
     * many {@link #FORMAT_TEXT} items, but only some of them may be {@link Slice#SUBTYPE_MESSAGE}.
     * @see #getFormat()
     */
    public String getSubType() {
        return mSubType;
    }

    /**
     * @return The text held by this {@link #FORMAT_TEXT} SliceItem
     */
    public CharSequence getText() {
        return (CharSequence) mObj;
    }

    /**
     * @return The parcelable held by this {@link #FORMAT_BUNDLE} SliceItem
     */
    public Bundle getBundle() {
        return (Bundle) mObj;
    }

    /**
     * @return The icon held by this {@link #FORMAT_IMAGE} SliceItem
     */
    public Icon getIcon() {
        return (Icon) mObj;
    }

    /**
     * @return The pending intent held by this {@link #FORMAT_ACTION} SliceItem
     */
    public PendingIntent getAction() {
        return ((Pair<PendingIntent, Slice>) mObj).first;
    }

    /**
     * @hide This isn't final
     */
    public RemoteViews getRemoteView() {
        return (RemoteViews) mObj;
    }

    /**
     * @return The remote input held by this {@link #FORMAT_REMOTE_INPUT} SliceItem
     */
    public RemoteInput getRemoteInput() {
        return (RemoteInput) mObj;
    }

    /**
     * @return The color held by this {@link #FORMAT_INT} SliceItem
     */
    public int getInt() {
        return (Integer) mObj;
    }

    /**
     * @return The slice held by this {@link #FORMAT_ACTION} or {@link #FORMAT_SLICE} SliceItem
     */
    public Slice getSlice() {
        if (FORMAT_ACTION.equals(getFormat())) {
            return ((Pair<PendingIntent, Slice>) mObj).second;
        }
        return (Slice) mObj;
    }

    /**
     * @return The long held by this {@link #FORMAT_LONG} SliceItem
     */
    public long getLong() {
        return (Long) mObj;
    }

    /**
     * @deprecated replaced by {@link #getLong()}
     * @removed
     */
    @Deprecated
    public long getTimestamp() {
        return (Long) mObj;
    }

    /**
     * @param hint The hint to check for
     * @return true if this item contains the given hint
     */
    public boolean hasHint(@Slice.SliceHint String hint) {
        return ArrayUtils.contains(mHints, hint);
    }

    /**
     * @hide
     */
    public SliceItem(Parcel in) {
        mHints = in.readStringArray();
        mFormat = in.readString();
        mSubType = in.readString();
        mObj = readObj(mFormat, in);
    }

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

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeStringArray(mHints);
        dest.writeString(mFormat);
        dest.writeString(mSubType);
        writeObj(dest, flags, mObj, mFormat);
    }

    /**
     * @hide
     */
    public boolean hasHints(@Slice.SliceHint String[] hints) {
        if (hints == null) return true;
        for (String hint : hints) {
            if (!TextUtils.isEmpty(hint) && !ArrayUtils.contains(mHints, hint)) {
                return false;
            }
        }
        return true;
    }

    /**
     * @hide
     */
    public boolean hasAnyHints(@Slice.SliceHint String[] hints) {
        if (hints == null) return false;
        for (String hint : hints) {
            if (ArrayUtils.contains(mHints, hint)) {
                return true;
            }
        }
        return false;
    }

    private static String getBaseType(String type) {
        int index = type.indexOf('/');
        if (index >= 0) {
            return type.substring(0, index);
        }
        return type;
    }

    private static void writeObj(Parcel dest, int flags, Object obj, String type) {
        switch (getBaseType(type)) {
            case FORMAT_SLICE:
            case FORMAT_IMAGE:
            case FORMAT_REMOTE_INPUT:
            case FORMAT_BUNDLE:
                ((Parcelable) obj).writeToParcel(dest, flags);
                break;
            case FORMAT_ACTION:
                ((Pair<PendingIntent, Slice>) obj).first.writeToParcel(dest, flags);
                ((Pair<PendingIntent, Slice>) obj).second.writeToParcel(dest, flags);
                break;
            case FORMAT_TEXT:
                TextUtils.writeToParcel((CharSequence) obj, dest, flags);
                break;
            case FORMAT_INT:
                dest.writeInt((Integer) obj);
                break;
            case FORMAT_TIMESTAMP:
                dest.writeLong((Long) obj);
                break;
        }
    }

    private static Object readObj(String type, Parcel in) {
        switch (getBaseType(type)) {
            case FORMAT_SLICE:
                return Slice.CREATOR.createFromParcel(in);
            case FORMAT_TEXT:
                return TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
            case FORMAT_IMAGE:
                return Icon.CREATOR.createFromParcel(in);
            case FORMAT_ACTION:
                return new Pair<>(
                        PendingIntent.CREATOR.createFromParcel(in),
                        Slice.CREATOR.createFromParcel(in));
            case FORMAT_INT:
                return in.readInt();
            case FORMAT_TIMESTAMP:
                return in.readLong();
            case FORMAT_REMOTE_INPUT:
                return RemoteInput.CREATOR.createFromParcel(in);
            case FORMAT_BUNDLE:
                return Bundle.CREATOR.createFromParcel(in);
        }
        throw new RuntimeException("Unsupported type " + type);
    }

    public static final @android.annotation.NonNull Creator<SliceItem> CREATOR = new Creator<SliceItem>() {
        @Override
        public SliceItem createFromParcel(Parcel in) {
            return new SliceItem(in);
        }

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