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

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.job.IJobCallback;
import android.content.ClipData;
import android.net.Uri;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.PersistableBundle;
import android.os.RemoteException;

/**
 * Contains the parameters used to configure/identify your job. You do not create this object
 * yourself, instead it is handed in to your application by the System.
 */
public class JobParameters implements Parcelable {

    /** @hide */
    public static final int REASON_CANCELED = 0;
    /** @hide */
    public static final int REASON_CONSTRAINTS_NOT_SATISFIED = 1;
    /** @hide */
    public static final int REASON_PREEMPT = 2;
    /** @hide */
    public static final int REASON_TIMEOUT = 3;
    /** @hide */
    public static final int REASON_DEVICE_IDLE = 4;

    private final int jobId;
    private final PersistableBundle extras;
    private final Bundle transientExtras;
    private final ClipData clipData;
    private final int clipGrantFlags;
    private final IBinder callback;
    private final boolean overrideDeadlineExpired;
    private final Uri[] mTriggeredContentUris;
    private final String[] mTriggeredContentAuthorities;

    private int stopReason; // Default value of stopReason is REASON_CANCELED

    /** @hide */
    public JobParameters(IBinder callback, int jobId, PersistableBundle extras,
            Bundle transientExtras, ClipData clipData, int clipGrantFlags,
            boolean overrideDeadlineExpired, Uri[] triggeredContentUris,
            String[] triggeredContentAuthorities) {
        this.jobId = jobId;
        this.extras = extras;
        this.transientExtras = transientExtras;
        this.clipData = clipData;
        this.clipGrantFlags = clipGrantFlags;
        this.callback = callback;
        this.overrideDeadlineExpired = overrideDeadlineExpired;
        this.mTriggeredContentUris = triggeredContentUris;
        this.mTriggeredContentAuthorities = triggeredContentAuthorities;
    }

    /**
     * @return The unique id of this job, specified at creation time.
     */
    public int getJobId() {
        return jobId;
    }

    /**
     * Reason onStopJob() was called on this job.
     * @hide
     */
    public int getStopReason() {
        return stopReason;
    }

    /**
     * @return The extras you passed in when constructing this job with
     * {@link android.app.job.JobInfo.Builder#setExtras(android.os.PersistableBundle)}. This will
     * never be null. If you did not set any extras this will be an empty bundle.
     */
    public @NonNull PersistableBundle getExtras() {
        return extras;
    }

    /**
     * @return The transient extras you passed in when constructing this job with
     * {@link android.app.job.JobInfo.Builder#setTransientExtras(android.os.Bundle)}. This will
     * never be null. If you did not set any extras this will be an empty bundle.
     */
    public @NonNull Bundle getTransientExtras() {
        return transientExtras;
    }

    /**
     * @return The clip you passed in when constructing this job with
     * {@link android.app.job.JobInfo.Builder#setClipData(ClipData, int)}. Will be null
     * if it was not set.
     */
    public @Nullable ClipData getClipData() {
        return clipData;
    }

    /**
     * @return The clip grant flags you passed in when constructing this job with
     * {@link android.app.job.JobInfo.Builder#setClipData(ClipData, int)}. Will be 0
     * if it was not set.
     */
    public int getClipGrantFlags() {
        return clipGrantFlags;
    }

    /**
     * For jobs with {@link android.app.job.JobInfo.Builder#setOverrideDeadline(long)} set, this
     * provides an easy way to tell whether the job is being executed due to the deadline
     * expiring. Note: If the job is running because its deadline expired, it implies that its
     * constraints will not be met.
     */
    public boolean isOverrideDeadlineExpired() {
        return overrideDeadlineExpired;
    }

    /**
     * For jobs with {@link android.app.job.JobInfo.Builder#addTriggerContentUri} set, this
     * reports which URIs have triggered the job.  This will be null if either no URIs have
     * triggered it (it went off due to a deadline or other reason), or the number of changed
     * URIs is too large to report.  Whether or not the number of URIs is too large, you can
     * always use {@link #getTriggeredContentAuthorities()} to determine whether the job was
     * triggered due to any content changes and the authorities they are associated with.
     */
    public @Nullable Uri[] getTriggeredContentUris() {
        return mTriggeredContentUris;
    }

    /**
     * For jobs with {@link android.app.job.JobInfo.Builder#addTriggerContentUri} set, this
     * reports which content authorities have triggered the job.  It will only be null if no
     * authorities have triggered it -- that is, the job executed for some other reason, such
     * as a deadline expiring.  If this is non-null, you can use {@link #getTriggeredContentUris()}
     * to retrieve the details of which URIs changed (as long as that has not exceeded the maximum
     * number it can reported).
     */
    public @Nullable String[] getTriggeredContentAuthorities() {
        return mTriggeredContentAuthorities;
    }

    /**
     * Dequeue the next pending {@link JobWorkItem} from these JobParameters associated with their
     * currently running job.  Calling this method when there is no more work available and all
     * previously dequeued work has been completed will result in the system taking care of
     * stopping the job for you --
     * you should not call {@link JobService#jobFinished(JobParameters, boolean)} yourself
     * (otherwise you risk losing an upcoming JobWorkItem that is being enqueued at the same time).
     *
     * <p>Once you are done with the {@link JobWorkItem} returned by this method, you must call
     * {@link #completeWork(JobWorkItem)} with it to inform the system that you are done
     * executing the work.  The job will not be finished until all dequeued work has been
     * completed.  You do not, however, have to complete each returned work item before deqeueing
     * the next one -- you can use {@link #dequeueWork()} multiple times before completing
     * previous work if you want to process work in parallel, and you can complete the work
     * in whatever order you want.</p>
     *
     * <p>If the job runs to the end of its available time period before all work has been
     * completed, it will stop as normal.  You should return true from
     * {@link JobService#onStopJob(JobParameters)} in order to have the job rescheduled, and by
     * doing so any pending as well as remaining uncompleted work will be re-queued
     * for the next time the job runs.</p>
     *
     * @return Returns a new {@link JobWorkItem} if there is one pending, otherwise null.
     * If null is returned, the system will also stop the job if all work has also been completed.
     * (This means that for correct operation, you must always call dequeueWork() after you have
     * completed other work, to check either for more work or allow the system to stop the job.)
     */
    public @Nullable JobWorkItem dequeueWork() {
        try {
            return getCallback().dequeueWork(getJobId());
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * Report the completion of executing a {@link JobWorkItem} previously returned by
     * {@link #dequeueWork()}.  This tells the system you are done with the
     * work associated with that item, so it will not be returned again.  Note that if this
     * is the last work in the queue, completing it here will <em>not</em> finish the overall
     * job -- for that to happen, you still need to call {@link #dequeueWork()}
     * again.
     *
     * <p>If you are enqueueing work into a job, you must call this method for each piece
     * of work you process.  Do <em>not</em> call
     * {@link JobService#jobFinished(JobParameters, boolean)}
     * or else you can lose work in your queue.</p>
     *
     * @param work The work you have completed processing, as previously returned by
     * {@link #dequeueWork()}
     */
    public void completeWork(@NonNull JobWorkItem work) {
        try {
            if (!getCallback().completeWork(getJobId(), work.getWorkId())) {
                throw new IllegalArgumentException("Given work is not active: " + work);
            }
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /** @hide */
    public IJobCallback getCallback() {
        return IJobCallback.Stub.asInterface(callback);
    }

    private JobParameters(Parcel in) {
        jobId = in.readInt();
        extras = in.readPersistableBundle();
        transientExtras = in.readBundle();
        if (in.readInt() != 0) {
            clipData = ClipData.CREATOR.createFromParcel(in);
            clipGrantFlags = in.readInt();
        } else {
            clipData = null;
            clipGrantFlags = 0;
        }
        callback = in.readStrongBinder();
        overrideDeadlineExpired = in.readInt() == 1;
        mTriggeredContentUris = in.createTypedArray(Uri.CREATOR);
        mTriggeredContentAuthorities = in.createStringArray();
        stopReason = in.readInt();
    }

    /** @hide */
    public void setStopReason(int reason) {
        stopReason = reason;
    }

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

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(jobId);
        dest.writePersistableBundle(extras);
        dest.writeBundle(transientExtras);
        if (clipData != null) {
            dest.writeInt(1);
            clipData.writeToParcel(dest, flags);
            dest.writeInt(clipGrantFlags);
        } else {
            dest.writeInt(0);
        }
        dest.writeStrongBinder(callback);
        dest.writeInt(overrideDeadlineExpired ? 1 : 0);
        dest.writeTypedArray(mTriggeredContentUris, flags);
        dest.writeStringArray(mTriggeredContentAuthorities);
        dest.writeInt(stopReason);
    }

    public static final Creator<JobParameters> CREATOR = new Creator<JobParameters>() {
        @Override
        public JobParameters createFromParcel(Parcel in) {
            return new JobParameters(in);
        }

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