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

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 java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/**
 * A representation of an app target event.
 *
 * @hide
 */
@SystemApi
@TestApi
public final class AppTargetEvent implements Parcelable {

    /**
     * @hide
     */
    @IntDef({ACTION_LAUNCH, ACTION_DISMISS, ACTION_PIN, ACTION_UNPIN})
    @Retention(RetentionPolicy.SOURCE)
    public @interface ActionType {}

    /**
     * Event type constant indicating an app target has been launched.
     */
    public static final int ACTION_LAUNCH = 1;

    /**
     * Event type constant indicating an app target has been dismissed.
     */
    public static final int ACTION_DISMISS = 2;

    /**
     * Event type constant indicating an app target has been pinned.
     */
    public static final int ACTION_PIN = 3;

    /**
     * Event type constant indicating an app target has been un-pinned.
     */
    public static final int ACTION_UNPIN = 4;

    private final AppTarget mTarget;
    private final String mLocation;
    private final int mAction;

    private AppTargetEvent(@Nullable AppTarget target, @Nullable String location,
            @ActionType int actionType) {
        mTarget = target;
        mLocation = location;
        mAction = actionType;
    }

    private AppTargetEvent(Parcel parcel) {
        mTarget = parcel.readParcelable(null);
        mLocation = parcel.readString();
        mAction = parcel.readInt();
    }

    /**
     * Returns the app target.
     */
    @Nullable
    public AppTarget getTarget() {
        return mTarget;
    }

    /**
     * Returns the launch location.
     */
    @Nullable
    public String getLaunchLocation() {
        return mLocation;
    }

    /**
     * Returns the action type.
     */
    public @ActionType int getAction() {
        return mAction;
    }

    @Override
    public boolean equals(@Nullable Object o) {
        if (!getClass().equals(o != null ? o.getClass() : null)) return false;

        AppTargetEvent other = (AppTargetEvent) o;
        return mTarget.equals(other.mTarget)
                && mLocation.equals(other.mLocation)
                && mAction == other.mAction;
    }

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

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeParcelable(mTarget, 0);
        dest.writeString(mLocation);
        dest.writeInt(mAction);
    }

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

                public AppTargetEvent[] newArray(int size) {
                    return new AppTargetEvent[size];
                }
            };

    /**
     * A builder for app target events.
     *
     * @hide
     */
    @SystemApi
    @TestApi
    public static final class Builder {
        private AppTarget mTarget;
        private String mLocation;
        private @ActionType int mAction;

        /**
         * @param target The app target that is associated with this event.
         * @param actionType The event type, which is one of the values in {@link ActionType}.
         */
        public Builder(@Nullable AppTarget target, @ActionType int actionType) {
            mTarget = target;
            mAction = actionType;
        }

        /**
         * Sets the launch location.
         */
        @NonNull
        public Builder setLaunchLocation(@Nullable String location) {
            mLocation = location;
            return this;
        }

        /**
         * Builds a new event instance.
         */
        @NonNull
        public AppTargetEvent build() {
            return new AppTargetEvent(mTarget, mLocation, mAction);
        }
    }
}
