/*
 * 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.ContentCaptureSession.NO_SESSION_ID;

import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Log;
import android.view.autofill.AutofillId;

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
@TestApi
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;


    /** @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
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface EventType{}

    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;

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

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

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

        }
    }

    @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();
            if (mNode != null) {
                string.append(", class=").append(className);
            }
            string.append(", id=").append(mNode.getAutofillId());
        }
        if (mText != null) {
            string.append(", text=").append(getSanitizedString(mText));
        }
        if (mClientContext != null) {
            string.append(", context=").append(mClientContext);
        }
        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);
        }
    }

    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));
            }
            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";
            default:
                return "UKNOWN_TYPE: " + type;
        }
    }
}
