/*
 * 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.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.content.Context;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;

/**
 * Class that provides contextual information about the environment in which the app prediction is
 * used, such as package name, UI in which the app targets are shown, and number of targets.
 *
 * @hide
 */
@SystemApi
@TestApi
public final class AppPredictionContext implements Parcelable {

    private final int mPredictedTargetCount;
    @NonNull
    private final String mUiSurface;
    @NonNull
    private final String mPackageName;
    @Nullable
    private final Bundle mExtras;

    private AppPredictionContext(@NonNull String uiSurface, int numPredictedTargets,
            @NonNull String packageName, @Nullable Bundle extras) {
        mUiSurface = uiSurface;
        mPredictedTargetCount = numPredictedTargets;
        mPackageName = packageName;
        mExtras = extras;
    }

    private AppPredictionContext(@NonNull Parcel parcel) {
        mUiSurface = parcel.readString();
        mPredictedTargetCount = parcel.readInt();
        mPackageName = parcel.readString();
        mExtras = parcel.readBundle();
    }

    /**
     * Returns the UI surface of the prediction context.
     */
    @NonNull
    public String getUiSurface() {
        return mUiSurface;
    }

    /**
     * Returns the predicted target count
     */
    public @IntRange(from = 0) int getPredictedTargetCount() {
        return mPredictedTargetCount;
    }

    /**
     * Returns the package name of the prediction context.
     */
    @NonNull
    public String getPackageName() {
        return mPackageName;
    }

    /**
     * Returns the extras of the prediction context.
     */
    @Nullable
    public Bundle getExtras() {
        return mExtras;
    }

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

        AppPredictionContext other = (AppPredictionContext) o;
        return mPredictedTargetCount == other.mPredictedTargetCount
                && mUiSurface.equals(other.mUiSurface)
                && mPackageName.equals(other.mPackageName);
    }

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

    @Override
    public void writeToParcel(@NonNull Parcel dest, int flags) {
        dest.writeString(mUiSurface);
        dest.writeInt(mPredictedTargetCount);
        dest.writeString(mPackageName);
        dest.writeBundle(mExtras);
    }

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

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

    /**
     * A builder for app prediction contexts.
     * @hide
     */
    @SystemApi
    @TestApi
    public static final class Builder {

        @NonNull
        private final String mPackageName;

        private int mPredictedTargetCount;
        @Nullable
        private String mUiSurface;
        @Nullable
        private Bundle mExtras;

        /**
         * @param context The {@link Context} of the prediction client.
         *
         * @hide
         */
        @SystemApi
        @TestApi
        public Builder(@NonNull Context context) {
            mPackageName = context.getPackageName();
        }


        /**
         * Sets the number of prediction targets as a hint.
         */
        @NonNull
        public Builder setPredictedTargetCount(@IntRange(from = 0) int predictedTargetCount) {
            mPredictedTargetCount = predictedTargetCount;
            return this;
        }

        /**
         * Sets the UI surface.
         */
        @NonNull
        public Builder setUiSurface(@NonNull String uiSurface) {
            mUiSurface = uiSurface;
            return this;
        }

        /**
         * Sets the extras.
         */
        @NonNull
        public Builder setExtras(@Nullable Bundle extras) {
            mExtras = extras;
            return this;
        }

        /**
         * Builds a new context instance.
         */
        @NonNull
        public AppPredictionContext build() {
            return new AppPredictionContext(mUiSurface, mPredictedTargetCount, mPackageName,
                    mExtras);
        }
    }
}
