/*
 * 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 androidx.app.slice;

import static android.app.slice.SliceItem.FORMAT_ACTION;
import static android.app.slice.SliceItem.FORMAT_IMAGE;
import static android.app.slice.SliceItem.FORMAT_INT;
import static android.app.slice.SliceItem.FORMAT_REMOTE_INPUT;
import static android.app.slice.SliceItem.FORMAT_SLICE;
import static android.app.slice.SliceItem.FORMAT_TEXT;
import static android.app.slice.SliceItem.FORMAT_TIMESTAMP;

import android.app.PendingIntent;
import android.app.RemoteInput;
import android.graphics.drawable.Icon;
import android.os.Bundle;
import android.os.Parcelable;
import android.support.annotation.NonNull;
import android.support.annotation.RequiresApi;
import android.support.annotation.RestrictTo;
import android.support.annotation.RestrictTo.Scope;
import android.support.annotation.StringDef;
import android.text.TextUtils;
import android.util.Pair;

import java.util.Arrays;
import java.util.List;


/**
 * A SliceItem is a single unit in the tree structure of a {@link Slice}.
 * <p>
 * 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 android.app.slice.SliceItem#FORMAT_SLICE}</li>
 * <li>{@link android.app.slice.SliceItem#FORMAT_TEXT}</li>
 * <li>{@link android.app.slice.SliceItem#FORMAT_IMAGE}</li>
 * <li>{@link android.app.slice.SliceItem#FORMAT_ACTION}</li>
 * <li>{@link android.app.slice.SliceItem#FORMAT_INT}</li>
 * <li>{@link android.app.slice.SliceItem#FORMAT_TIMESTAMP}</li>
 * <p>
 * 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 class SliceItem {

    private static final String HINTS = "hints";
    private static final String FORMAT = "format";
    private static final String SUBTYPE = "subtype";
    private static final String OBJ = "obj";
    private static final String OBJ_2 = "obj_2";

    /**
     * @hide
     */
    @RestrictTo(Scope.LIBRARY)
    @StringDef({FORMAT_SLICE, FORMAT_TEXT, FORMAT_IMAGE, FORMAT_ACTION, FORMAT_INT,
            FORMAT_TIMESTAMP, FORMAT_REMOTE_INPUT})
    public @interface SliceType {
    }

    /**
     * @hide
     */
    @RestrictTo(Scope.LIBRARY)
    protected @Slice.SliceHint String[] mHints;
    private final String mFormat;
    private final String mSubType;
    private final Object mObj;

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

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

    /**
     * @hide
     */
    @RestrictTo(Scope.LIBRARY)
    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);
    }

    /**
     * @hide
     */
    @RestrictTo(Scope.LIBRARY)
    public void addHint(@Slice.SliceHint String hint) {
        mHints = ArrayUtils.appendElement(String.class, mHints, hint);
    }

    /**
     * @hide
     */
    @RestrictTo(Scope.LIBRARY)
    public void removeHint(String hint) {
        ArrayUtils.removeElement(String.class, mHints, hint);
    }

    /**
     * Get the format of this SliceItem.
     * <p>
     * The format will be one of the following types supported by the platform:
     * <li>{@link android.app.slice.SliceItem#FORMAT_SLICE}</li>
     * <li>{@link android.app.slice.SliceItem#FORMAT_TEXT}</li>
     * <li>{@link android.app.slice.SliceItem#FORMAT_IMAGE}</li>
     * <li>{@link android.app.slice.SliceItem#FORMAT_ACTION}</li>
     * <li>{@link android.app.slice.SliceItem#FORMAT_INT}</li>
     * <li>{@link android.app.slice.SliceItem#FORMAT_TIMESTAMP}</li>
     * <li>{@link android.app.slice.SliceItem#FORMAT_REMOTE_INPUT}</li>
     * @see #getSubType() ()
     */
    public @SliceType 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 android.app.slice.SliceItem#FORMAT_TEXT} items, but only some of them may be
     * {@link android.app.slice.Slice#SUBTYPE_MESSAGE}.
     * @see #getFormat()
     */
    public String getSubType() {
        return mSubType;
    }

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

    /**
     * @return The icon held by this {@link android.app.slice.SliceItem#FORMAT_IMAGE} SliceItem
     */
    @RequiresApi(23)
    public Icon getIcon() {
        return (Icon) mObj;
    }

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

    /**
     * @return The remote input held by this {@link android.app.slice.SliceItem#FORMAT_REMOTE_INPUT}
     * SliceItem
     * @hide
     */
    @RequiresApi(20)
    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
    public RemoteInput getRemoteInput() {
        return (RemoteInput) mObj;
    }

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

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

    /**
     * @return The timestamp held by this {@link android.app.slice.SliceItem#FORMAT_TIMESTAMP}
     * SliceItem
     */
    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
     */
    @RestrictTo(Scope.LIBRARY)
    public SliceItem(Bundle in) {
        mHints = in.getStringArray(HINTS);
        mFormat = in.getString(FORMAT);
        mSubType = in.getString(SUBTYPE);
        mObj = readObj(mFormat, in);
    }

    /**
     * @hide
     * @return
     */
    @RestrictTo(Scope.LIBRARY)
    public Bundle toBundle() {
        Bundle b = new Bundle();
        b.putStringArray(HINTS, mHints);
        b.putString(FORMAT, mFormat);
        b.putString(SUBTYPE, mSubType);
        writeObj(b, mObj, mFormat);
        return b;
    }

    /**
     * @hide
     */
    @RestrictTo(Scope.LIBRARY)
    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
     */
    @RestrictTo(Scope.LIBRARY)
    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 void writeObj(Bundle dest, Object obj, String type) {
        switch (type) {
            case FORMAT_IMAGE:
            case FORMAT_REMOTE_INPUT:
                dest.putParcelable(OBJ, (Parcelable) obj);
                break;
            case FORMAT_SLICE:
                dest.putParcelable(OBJ, ((Slice) obj).toBundle());
                break;
            case FORMAT_ACTION:
                dest.putParcelable(OBJ, ((Pair<PendingIntent, Slice>) obj).first);
                dest.putBundle(OBJ_2, ((Pair<PendingIntent, Slice>) obj).second.toBundle());
                break;
            case FORMAT_TEXT:
                dest.putCharSequence(OBJ, (CharSequence) obj);
                break;
            case FORMAT_INT:
                dest.putInt(OBJ, (Integer) mObj);
                break;
            case FORMAT_TIMESTAMP:
                dest.putLong(OBJ, (Long) mObj);
                break;
        }
    }

    private static Object readObj(String type, Bundle in) {
        switch (type) {
            case FORMAT_IMAGE:
            case FORMAT_REMOTE_INPUT:
                return in.getParcelable(OBJ);
            case FORMAT_SLICE:
                return new Slice(in.getBundle(OBJ));
            case FORMAT_TEXT:
                return in.getCharSequence(OBJ);
            case FORMAT_ACTION:
                return new Pair<>(
                        (PendingIntent) in.getParcelable(OBJ),
                        new Slice(in.getBundle(OBJ_2)));
            case FORMAT_INT:
                return in.getInt(OBJ);
            case FORMAT_TIMESTAMP:
                return in.getLong(OBJ);
        }
        throw new RuntimeException("Unsupported type " + type);
    }

    /**
     * @hide
     */
    @RestrictTo(Scope.LIBRARY)
    public static String typeToString(String format) {
        switch (format) {
            case FORMAT_SLICE:
                return "Slice";
            case FORMAT_TEXT:
                return "Text";
            case FORMAT_IMAGE:
                return "Image";
            case FORMAT_ACTION:
                return "Action";
            case FORMAT_INT:
                return "Int";
            case FORMAT_TIMESTAMP:
                return "Timestamp";
            case FORMAT_REMOTE_INPUT:
                return "RemoteInput";
        }
        return "Unrecognized format: " + format;
    }

    /**
     * @hide
     * @return A string representation of this slice item.
     */
    @RestrictTo(Scope.LIBRARY)
    @Override
    public String toString() {
        return toString("");
    }

    private String toString(String indent) {
        StringBuilder sb = new StringBuilder();
        sb.append(indent);
        if (FORMAT_SLICE.equals(mFormat)) {
            sb.append("slice:\n");
            sb.append(getSlice().toString(indent + "   "));
        } else if (FORMAT_ACTION.equals(mFormat)) {
            sb.append("action:\n");
            sb.append(getSlice().toString(indent + "   "));
        } else if (FORMAT_TEXT.equals(mFormat)) {
            sb.append("text: ");
            sb.append(getText());
            sb.append("\n");
        } else {
            sb.append(SliceItem.typeToString(getFormat()));
            sb.append("\n");
        }
        return sb.toString();
    }
}
