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

import static android.view.contentcapture.ContentCaptureHelper.getSanitizedString;
import static android.view.contentcapture.ContentCaptureManager.DEBUG;
import static android.view.contentcapture.ContentCaptureManager.NO_SESSION_ID;

import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.graphics.Insets;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.Selection;
import android.text.Spannable;
import android.text.SpannableString;
import android.util.Log;
import android.view.autofill.AutofillId;
import android.view.inputmethod.BaseInputConnection;

import com.android.internal.util.Preconditions;

import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.List;

/** @hide */
@SystemApi
public final class ContentCaptureEvent implements Parcelable {

    private static final String TAG = ContentCaptureEvent.class.getSimpleName();

    /** @hide */
    public static final int TYPE_SESSION_FINISHED = -2;
    /** @hide */
    public static final int TYPE_SESSION_STARTED = -1;

    /**
     * Called when a node has been added to the screen and is visible to the user.
     *
     * <p>The metadata of the node is available through {@link #getViewNode()}.
     */
    public static final int TYPE_VIEW_APPEARED = 1;

    /**
     * Called when one or more nodes have been removed from the screen and is not visible to the
     * user anymore.
     *
     * <p>To get the id(s), first call {@link #getIds()} - if it returns {@code null}, then call
     * {@link #getId()}.
     */
    public static final int TYPE_VIEW_DISAPPEARED = 2;

    /**
     * Called when the text of a node has been changed.
     *
     * <p>The id of the node is available through {@link #getId()}, and the new text is
     * available through {@link #getText()}.
     */
    public static final int TYPE_VIEW_TEXT_CHANGED = 3;

    /**
     * Called before events (such as {@link #TYPE_VIEW_APPEARED} and/or
     * {@link #TYPE_VIEW_DISAPPEARED}) representing a view hierarchy are sent.
     *
     * <p><b>NOTE</b>: there is no guarantee this event will be sent. For example, it's not sent
     * if the initial view hierarchy doesn't initially have any view that's important for content
     * capture.
     */
    public static final int TYPE_VIEW_TREE_APPEARING = 4;

    /**
     * Called after events (such as {@link #TYPE_VIEW_APPEARED} and/or
     * {@link #TYPE_VIEW_DISAPPEARED}) representing a view hierarchy were sent.
     *
     * <p><b>NOTE</b>: there is no guarantee this event will be sent. For example, it's not sent
     * if the initial view hierarchy doesn't initially have any view that's important for content
     * capture.
     */
    public static final int TYPE_VIEW_TREE_APPEARED = 5;

    /**
     * Called after a call to
     * {@link ContentCaptureSession#setContentCaptureContext(ContentCaptureContext)}.
     *
     * <p>The passed context is available through {@link #getContentCaptureContext()}.
     */
    public static final int TYPE_CONTEXT_UPDATED = 6;

    /**
     * Called after the session is ready, typically after the activity resumed and the
     * initial views appeared
     */
    public static final int TYPE_SESSION_RESUMED = 7;

    /**
     * Called after the session is paused, typically after the activity paused and the
     * views disappeared.
     */
    public static final int TYPE_SESSION_PAUSED = 8;

    /**
     * Called when the view's insets are changed. The new insets associated with the
     * event may then be retrieved by calling {@link #getInsets()}
     */
    public static final int TYPE_VIEW_INSETS_CHANGED = 9;

    /** @hide */
    @IntDef(prefix = { "TYPE_" }, value = {
            TYPE_VIEW_APPEARED,
            TYPE_VIEW_DISAPPEARED,
            TYPE_VIEW_TEXT_CHANGED,
            TYPE_VIEW_TREE_APPEARING,
            TYPE_VIEW_TREE_APPEARED,
            TYPE_CONTEXT_UPDATED,
            TYPE_SESSION_PAUSED,
            TYPE_SESSION_RESUMED,
            TYPE_VIEW_INSETS_CHANGED
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface EventType{}

    /** @hide */
    public static final int MAX_INVALID_VALUE = -1;

    private final int mSessionId;
    private final int mType;
    private final long mEventTime;
    private @Nullable AutofillId mId;
    private @Nullable ArrayList<AutofillId> mIds;
    private @Nullable ViewNode mNode;
    private @Nullable CharSequence mText;
    private int mParentSessionId = NO_SESSION_ID;
    private @Nullable ContentCaptureContext mClientContext;
    private @Nullable Insets mInsets;

    private int mComposingStart = MAX_INVALID_VALUE;
    private int mComposingEnd = MAX_INVALID_VALUE;
    private int mSelectionStartIndex = MAX_INVALID_VALUE;
    private int mSelectionEndIndex = MAX_INVALID_VALUE;

    /** Only used in the main Content Capture session, no need to parcel */
    private boolean mTextHasComposingSpan;

    /** @hide */
    public ContentCaptureEvent(int sessionId, int type, long eventTime) {
        mSessionId = sessionId;
        mType = type;
        mEventTime = eventTime;
    }

    /** @hide */
    public ContentCaptureEvent(int sessionId, int type) {
        this(sessionId, type, System.currentTimeMillis());
    }

    /** @hide */
    public ContentCaptureEvent setAutofillId(@NonNull AutofillId id) {
        mId = Preconditions.checkNotNull(id);
        return this;
    }

    /** @hide */
    public ContentCaptureEvent setAutofillIds(@NonNull ArrayList<AutofillId> ids) {
        mIds = Preconditions.checkNotNull(ids);
        return this;
    }

    /**
     * Adds an autofill id to the this event, merging the single id into a list if necessary.
     *
     * @hide
     */
    public ContentCaptureEvent addAutofillId(@NonNull AutofillId id) {
        Preconditions.checkNotNull(id);
        if (mIds == null) {
            mIds = new ArrayList<>();
            if (mId == null) {
                Log.w(TAG, "addAutofillId(" + id + ") called without an initial id");
            } else {
                mIds.add(mId);
                mId = null;
            }
        }
        mIds.add(id);
        return this;
    }

    /**
     * Used by {@link #TYPE_SESSION_STARTED} and {@link #TYPE_SESSION_FINISHED}.
     *
     * @hide
     */
    public ContentCaptureEvent setParentSessionId(int parentSessionId) {
        mParentSessionId = parentSessionId;
        return this;
    }

    /**
     * Used by {@link #TYPE_SESSION_STARTED} and {@link #TYPE_SESSION_FINISHED}.
     *
     * @hide
     */
    public ContentCaptureEvent setClientContext(@NonNull ContentCaptureContext clientContext) {
        mClientContext = clientContext;
        return this;
    }

    /** @hide */
    @NonNull
    public int getSessionId() {
        return mSessionId;
    }

    /**
     * Used by {@link #TYPE_SESSION_STARTED} and {@link #TYPE_SESSION_FINISHED}.
     *
     * @hide
     */
    @Nullable
    public int getParentSessionId() {
        return mParentSessionId;
    }

    /**
     * Gets the {@link ContentCaptureContext} set calls to
     * {@link ContentCaptureSession#setContentCaptureContext(ContentCaptureContext)}.
     *
     * <p>Only set on {@link #TYPE_CONTEXT_UPDATED} events.
     */
    @Nullable
    public ContentCaptureContext getContentCaptureContext() {
        return mClientContext;
    }

    /** @hide */
    @NonNull
    public ContentCaptureEvent setViewNode(@NonNull ViewNode node) {
        mNode = Preconditions.checkNotNull(node);
        return this;
    }

    /** @hide */
    @NonNull
    public ContentCaptureEvent setText(@Nullable CharSequence text) {
        mText = text;
        return this;
    }

    /** @hide */
    @NonNull
    public ContentCaptureEvent setComposingIndex(int start, int end) {
        mComposingStart = start;
        mComposingEnd = end;
        return this;
    }

    /** @hide */
    @NonNull
    public boolean hasComposingSpan() {
        return mComposingStart > MAX_INVALID_VALUE;
    }

    /** @hide */
    @NonNull
    public ContentCaptureEvent setSelectionIndex(int start, int end) {
        mSelectionStartIndex = start;
        mSelectionEndIndex = end;
        return this;
    }

    boolean hasSameComposingSpan(@NonNull ContentCaptureEvent other) {
        return mComposingStart == other.mComposingStart && mComposingEnd == other.mComposingEnd;
    }

    boolean hasSameSelectionSpan(@NonNull ContentCaptureEvent other) {
        return mSelectionStartIndex == other.mSelectionStartIndex
                && mSelectionEndIndex == other.mSelectionEndIndex;
    }

    private int getComposingStart() {
        return mComposingStart;
    }

    private int getComposingEnd() {
        return mComposingEnd;
    }

    private int getSelectionStart() {
        return mSelectionStartIndex;
    }

    private int getSelectionEnd() {
        return mSelectionEndIndex;
    }

    private void restoreComposingSpan() {
        if (mComposingStart <= MAX_INVALID_VALUE
                || mComposingEnd <= MAX_INVALID_VALUE) {
            return;
        }
        if (mText instanceof Spannable) {
            BaseInputConnection.setComposingSpans((Spannable) mText, mComposingStart,
                    mComposingEnd);
        } else {
            Log.w(TAG, "Text is not a Spannable.");
        }
    }

    private void restoreSelectionSpans() {
        if (mSelectionStartIndex <= MAX_INVALID_VALUE
                || mSelectionEndIndex <= MAX_INVALID_VALUE) {
            return;
        }

        if (mText instanceof SpannableString) {
            SpannableString ss = (SpannableString) mText;
            ss.setSpan(Selection.SELECTION_START, mSelectionStartIndex, mSelectionStartIndex, 0);
            ss.setSpan(Selection.SELECTION_END, mSelectionEndIndex, mSelectionEndIndex, 0);
        } else {
            Log.w(TAG, "Text is not a SpannableString.");
        }
    }

    /** @hide */
    @NonNull
    public ContentCaptureEvent setInsets(@NonNull Insets insets) {
        mInsets = insets;
        return this;
    }

    /**
     * Gets the type of the event.
     *
     * @return one of {@link #TYPE_VIEW_APPEARED}, {@link #TYPE_VIEW_DISAPPEARED},
     * {@link #TYPE_VIEW_TEXT_CHANGED}, {@link #TYPE_VIEW_TREE_APPEARING},
     * {@link #TYPE_VIEW_TREE_APPEARED}, {@link #TYPE_CONTEXT_UPDATED},
     * {@link #TYPE_SESSION_RESUMED}, or {@link #TYPE_SESSION_PAUSED}.
     */
    public @EventType int getType() {
        return mType;
    }

    /**
     * Gets when the event was generated, in millis since epoch.
     */
    public long getEventTime() {
        return mEventTime;
    }

    /**
     * Gets the whole metadata of the node associated with the event.
     *
     * <p>Only set on {@link #TYPE_VIEW_APPEARED} events.
     */
    @Nullable
    public ViewNode getViewNode() {
        return mNode;
    }

    /**
     * Gets the {@link AutofillId} of the node associated with the event.
     *
     * <p>Only set on {@link #TYPE_VIEW_DISAPPEARED} (when the event contains just one node - if
     * it contains more than one, this method returns {@code null} and the actual ids should be
     * retrived by {@link #getIds()}) and {@link #TYPE_VIEW_TEXT_CHANGED} events.
     */
    @Nullable
    public AutofillId getId() {
        return mId;
    }

    /**
     * Gets the {@link AutofillId AutofillIds} of the nodes associated with the event.
     *
     * <p>Only set on {@link #TYPE_VIEW_DISAPPEARED}, when the event contains more than one node
     * (if it contains just one node, it's returned by {@link #getId()} instead.
     */
    @Nullable
    public List<AutofillId> getIds() {
        return mIds;
    }

    /**
     * Gets the current text of the node associated with the event.
     *
     * <p>Only set on {@link #TYPE_VIEW_TEXT_CHANGED} events.
     */
    @Nullable
    public CharSequence getText() {
        return mText;
    }

    /**
     * Gets the rectangle of the insets associated with the event. Valid insets will only be
     * returned if the type of the event is {@link #TYPE_VIEW_INSETS_CHANGED}, otherwise they
     * will be null.
     */
    @Nullable
    public Insets getInsets() {
        return mInsets;
    }

    /**
     * Merges event of the same type, either {@link #TYPE_VIEW_TEXT_CHANGED}
     * or {@link #TYPE_VIEW_DISAPPEARED}.
     *
     * @hide
     */
    public void mergeEvent(@NonNull ContentCaptureEvent event) {
        Preconditions.checkNotNull(event);
        final int eventType = event.getType();
        if (mType != eventType) {
            Log.e(TAG, "mergeEvent(" + getTypeAsString(eventType) + ") cannot be merged "
                    + "with different eventType=" + getTypeAsString(mType));
            return;
        }

        if (eventType == TYPE_VIEW_DISAPPEARED) {
            final List<AutofillId> ids = event.getIds();
            final AutofillId id = event.getId();
            if (ids != null) {
                if (id != null) {
                    Log.w(TAG, "got TYPE_VIEW_DISAPPEARED event with both id and ids: " + event);
                }
                for (int i = 0; i < ids.size(); i++) {
                    addAutofillId(ids.get(i));
                }
                return;
            }
            if (id != null) {
                addAutofillId(id);
                return;
            }
            throw new IllegalArgumentException("mergeEvent(): got "
                    + "TYPE_VIEW_DISAPPEARED event with neither id or ids: " + event);
        } else if (eventType == TYPE_VIEW_TEXT_CHANGED) {
            setText(event.getText());
            setComposingIndex(event.getComposingStart(), event.getComposingEnd());
            setSelectionIndex(event.getSelectionStart(), event.getSelectionEnd());
        } else {
            Log.e(TAG, "mergeEvent(" + getTypeAsString(eventType)
                    + ") does not support this event type.");
        }
    }

    /** @hide */
    public void dump(@NonNull PrintWriter pw) {
        pw.print("type="); pw.print(getTypeAsString(mType));
        pw.print(", time="); pw.print(mEventTime);
        if (mId != null) {
            pw.print(", id="); pw.print(mId);
        }
        if (mIds != null) {
            pw.print(", ids="); pw.print(mIds);
        }
        if (mNode != null) {
            pw.print(", mNode.id="); pw.print(mNode.getAutofillId());
        }
        if (mSessionId != NO_SESSION_ID) {
            pw.print(", sessionId="); pw.print(mSessionId);
        }
        if (mParentSessionId != NO_SESSION_ID) {
            pw.print(", parentSessionId="); pw.print(mParentSessionId);
        }
        if (mText != null) {
            pw.print(", text="); pw.println(getSanitizedString(mText));
        }
        if (mClientContext != null) {
            pw.print(", context="); mClientContext.dump(pw); pw.println();
        }
        if (mInsets != null) {
            pw.print(", insets="); pw.println(mInsets);
        }
        if (mComposingStart > MAX_INVALID_VALUE) {
            pw.print(", composing("); pw.print(mComposingStart);
            pw.print(", "); pw.print(mComposingEnd); pw.print(")");
        }
        if (mSelectionStartIndex > MAX_INVALID_VALUE) {
            pw.print(", selection("); pw.print(mSelectionStartIndex);
            pw.print(", "); pw.print(mSelectionEndIndex); pw.print(")");
        }
    }

    @NonNull
    @Override
    public String toString() {
        final StringBuilder string = new StringBuilder("ContentCaptureEvent[type=")
                .append(getTypeAsString(mType));
        string.append(", session=").append(mSessionId);
        if (mType == TYPE_SESSION_STARTED && mParentSessionId != NO_SESSION_ID) {
            string.append(", parent=").append(mParentSessionId);
        }
        if (mId != null) {
            string.append(", id=").append(mId);
        }
        if (mIds != null) {
            string.append(", ids=").append(mIds);
        }
        if (mNode != null) {
            final String className = mNode.getClassName();
            string.append(", class=").append(className);
            string.append(", id=").append(mNode.getAutofillId());
            if (mNode.getText() != null) {
                string.append(", text=")
                        .append(DEBUG ? mNode.getText() : getSanitizedString(mNode.getText()));
            }
        }
        if (mText != null) {
            string.append(", text=")
                    .append(DEBUG ? mText : getSanitizedString(mText));
        }
        if (mClientContext != null) {
            string.append(", context=").append(mClientContext);
        }
        if (mInsets != null) {
            string.append(", insets=").append(mInsets);
        }
        if (mComposingStart > MAX_INVALID_VALUE) {
            string.append(", composing=[")
                    .append(mComposingStart).append(",").append(mComposingEnd).append("]");
        }
        if (mSelectionStartIndex > MAX_INVALID_VALUE) {
            string.append(", selection=[")
                    .append(mSelectionStartIndex).append(",")
                    .append(mSelectionEndIndex).append("]");
        }
        return string.append(']').toString();
    }

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

    @Override
    public void writeToParcel(Parcel parcel, int flags) {
        parcel.writeInt(mSessionId);
        parcel.writeInt(mType);
        parcel.writeLong(mEventTime);
        parcel.writeParcelable(mId, flags);
        parcel.writeTypedList(mIds);
        ViewNode.writeToParcel(parcel, mNode, flags);
        parcel.writeCharSequence(mText);
        if (mType == TYPE_SESSION_STARTED || mType == TYPE_SESSION_FINISHED) {
            parcel.writeInt(mParentSessionId);
        }
        if (mType == TYPE_SESSION_STARTED || mType == TYPE_CONTEXT_UPDATED) {
            parcel.writeParcelable(mClientContext, flags);
        }
        if (mType == TYPE_VIEW_INSETS_CHANGED) {
            parcel.writeParcelable(mInsets, flags);
        }
        if (mType == TYPE_VIEW_TEXT_CHANGED) {
            parcel.writeInt(mComposingStart);
            parcel.writeInt(mComposingEnd);
            parcel.writeInt(mSelectionStartIndex);
            parcel.writeInt(mSelectionEndIndex);
        }
    }

    public static final @android.annotation.NonNull Parcelable.Creator<ContentCaptureEvent> CREATOR =
            new Parcelable.Creator<ContentCaptureEvent>() {

        @Override
        @NonNull
        public ContentCaptureEvent createFromParcel(Parcel parcel) {
            final int sessionId = parcel.readInt();
            final int type = parcel.readInt();
            final long eventTime  = parcel.readLong();
            final ContentCaptureEvent event = new ContentCaptureEvent(sessionId, type, eventTime);
            final AutofillId id = parcel.readParcelable(null);
            if (id != null) {
                event.setAutofillId(id);
            }
            final ArrayList<AutofillId> ids = parcel.createTypedArrayList(AutofillId.CREATOR);
            if (ids != null) {
                event.setAutofillIds(ids);
            }
            final ViewNode node = ViewNode.readFromParcel(parcel);
            if (node != null) {
                event.setViewNode(node);
            }
            event.setText(parcel.readCharSequence());
            if (type == TYPE_SESSION_STARTED || type == TYPE_SESSION_FINISHED) {
                event.setParentSessionId(parcel.readInt());
            }
            if (type == TYPE_SESSION_STARTED || type == TYPE_CONTEXT_UPDATED) {
                event.setClientContext(parcel.readParcelable(null));
            }
            if (type == TYPE_VIEW_INSETS_CHANGED) {
                event.setInsets(parcel.readParcelable(null));
            }
            if (type == TYPE_VIEW_TEXT_CHANGED) {
                event.setComposingIndex(parcel.readInt(), parcel.readInt());
                event.restoreComposingSpan();
                event.setSelectionIndex(parcel.readInt(), parcel.readInt());
                event.restoreSelectionSpans();
            }
            return event;
        }

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

    /** @hide */
    public static String getTypeAsString(@EventType int type) {
        switch (type) {
            case TYPE_SESSION_STARTED:
                return "SESSION_STARTED";
            case TYPE_SESSION_FINISHED:
                return "SESSION_FINISHED";
            case TYPE_SESSION_RESUMED:
                return "SESSION_RESUMED";
            case TYPE_SESSION_PAUSED:
                return "SESSION_PAUSED";
            case TYPE_VIEW_APPEARED:
                return "VIEW_APPEARED";
            case TYPE_VIEW_DISAPPEARED:
                return "VIEW_DISAPPEARED";
            case TYPE_VIEW_TEXT_CHANGED:
                return "VIEW_TEXT_CHANGED";
            case TYPE_VIEW_TREE_APPEARING:
                return "VIEW_TREE_APPEARING";
            case TYPE_VIEW_TREE_APPEARED:
                return "VIEW_TREE_APPEARED";
            case TYPE_CONTEXT_UPDATED:
                return "CONTEXT_UPDATED";
            case TYPE_VIEW_INSETS_CHANGED:
                return "VIEW_INSETS_CHANGED";
            default:
                return "UKNOWN_TYPE: " + type;
        }
    }
}
