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

import android.annotation.FloatRange;
import android.annotation.IntDef;
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.StringRes;
import android.annotation.TestApi;
import android.annotation.UnsupportedAppUsage;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.service.print.PrintJobInfoProto;

import com.android.internal.util.Preconditions;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Arrays;

/**
 * This class represents the description of a print job. The print job
 * state includes properties such as its id, print attributes used for
 * generating the content, and so on. Note that the print jobs state may
 * change over time and this class represents a snapshot of this state.
 */
public final class PrintJobInfo implements Parcelable {

    /** @hide */
    @IntDef(prefix = { "STATE_" }, value = {
            STATE_CREATED,
            STATE_QUEUED,
            STATE_STARTED,
            STATE_BLOCKED,
            STATE_COMPLETED,
            STATE_FAILED,
            STATE_CANCELED
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface State {
    }

    /**
     * Constant for matching any print job state.
     *
     * @hide
     */
    public static final int STATE_ANY = -1;

    /**
     * Constant for matching any print job state.
     *
     * @hide
     */
    public static final int STATE_ANY_VISIBLE_TO_CLIENTS = -2;

    /**
     * Constant for matching any active print job state.
     *
     * @hide
     */
    public static final int STATE_ANY_ACTIVE = -3;

    /**
     * Constant for matching any scheduled, i.e. delivered to a print
     * service, print job state.
     *
     * @hide
     */
    public static final int STATE_ANY_SCHEDULED = -4;

    /**
     * Print job state: The print job is being created but not yet
     * ready to be printed.
     * <p>
     * Next valid states: {@link #STATE_QUEUED}
     * </p>
     */
    public static final int STATE_CREATED = PrintJobInfoProto.STATE_CREATED;

    /**
     * Print job state: The print jobs is created, it is ready
     * to be printed and should be processed.
     * <p>
     * Next valid states: {@link #STATE_STARTED}, {@link #STATE_FAILED},
     * {@link #STATE_CANCELED}
     * </p>
     */
    public static final int STATE_QUEUED = PrintJobInfoProto.STATE_QUEUED;

    /**
     * Print job state: The print job is being printed.
     * <p>
     * Next valid states: {@link #STATE_COMPLETED}, {@link #STATE_FAILED},
     * {@link #STATE_CANCELED}, {@link #STATE_BLOCKED}
     * </p>
     */
    public static final int STATE_STARTED = PrintJobInfoProto.STATE_STARTED;

    /**
     * Print job state: The print job is blocked.
     * <p>
     * Next valid states: {@link #STATE_FAILED}, {@link #STATE_CANCELED},
     * {@link #STATE_STARTED}
     * </p>
     */
    public static final int STATE_BLOCKED = PrintJobInfoProto.STATE_BLOCKED;

    /**
     * Print job state: The print job is successfully printed.
     * This is a terminal state.
     * <p>
     * Next valid states: None
     * </p>
     */
    public static final int STATE_COMPLETED = PrintJobInfoProto.STATE_COMPLETED;

    /**
     * Print job state: The print job was printing but printing failed.
     * <p>
     * Next valid states: {@link #STATE_CANCELED}, {@link #STATE_STARTED}
     * </p>
     */
    public static final int STATE_FAILED = PrintJobInfoProto.STATE_FAILED;

    /**
     * Print job state: The print job is canceled.
     * This is a terminal state.
     * <p>
     * Next valid states: None
     * </p>
     */
    public static final int STATE_CANCELED = PrintJobInfoProto.STATE_CANCELED;

    /** The unique print job id. */
    private PrintJobId mId;

    /** The human readable print job label. */
    private String mLabel;

    /** The unique id of the printer. */
    private PrinterId mPrinterId;

    /** The name of the printer - internally used */
    private String mPrinterName;

    /** The state of the print job. */
    private int mState;

    /** The id of the app that created the job. */
    private int mAppId;

    /** Optional tag assigned by a print service.*/
    private String mTag;

    /** The wall time when the print job was created. */
    private long mCreationTime;

    /** How many copies to print. */
    private int mCopies;

    /** The pages to print */
    private PageRange[] mPageRanges;

    /** The print job attributes size. */
    private PrintAttributes mAttributes;

    /** Information about the printed document. */
    private PrintDocumentInfo mDocumentInfo;

    /** The progress made on printing this job or -1 if not set. */
    private float mProgress;

    /** A short string describing the status of this job. */
    private @Nullable CharSequence mStatus;

    /** A string resource describing the status of this job. */
    private @StringRes int mStatusRes;
    private @Nullable CharSequence mStatusResAppPackageName;

    /** Advanced printer specific options. */
    private Bundle mAdvancedOptions;

    /** Whether we are trying to cancel this print job. */
    private boolean mCanceling;

    /** @hide*/
    public PrintJobInfo() {
        mProgress = -1;
    }

    /** @hide */
    public PrintJobInfo(PrintJobInfo other) {
        mId = other.mId;
        mLabel = other.mLabel;
        mPrinterId = other.mPrinterId;
        mPrinterName = other.mPrinterName;
        mState = other.mState;
        mAppId = other.mAppId;
        mTag = other.mTag;
        mCreationTime = other.mCreationTime;
        mCopies = other.mCopies;
        mPageRanges = other.mPageRanges;
        mAttributes = other.mAttributes;
        mDocumentInfo = other.mDocumentInfo;
        mProgress = other.mProgress;
        mStatus = other.mStatus;
        mStatusRes = other.mStatusRes;
        mStatusResAppPackageName = other.mStatusResAppPackageName;
        mCanceling = other.mCanceling;
        mAdvancedOptions = other.mAdvancedOptions;
    }

    private PrintJobInfo(@NonNull Parcel parcel) {
        mId = parcel.readParcelable(null);
        mLabel = parcel.readString();
        mPrinterId = parcel.readParcelable(null);
        mPrinterName = parcel.readString();
        mState = parcel.readInt();
        mAppId = parcel.readInt();
        mTag = parcel.readString();
        mCreationTime = parcel.readLong();
        mCopies = parcel.readInt();
        Parcelable[] parcelables = parcel.readParcelableArray(null);
        if (parcelables != null) {
            mPageRanges = new PageRange[parcelables.length];
            for (int i = 0; i < parcelables.length; i++) {
                mPageRanges[i] = (PageRange) parcelables[i];
            }
        }
        mAttributes = (PrintAttributes) parcel.readParcelable(null);
        mDocumentInfo = (PrintDocumentInfo) parcel.readParcelable(null);
        mProgress = parcel.readFloat();
        mStatus = parcel.readCharSequence();
        mStatusRes = parcel.readInt();
        mStatusResAppPackageName = parcel.readCharSequence();
        mCanceling = (parcel.readInt() == 1);
        mAdvancedOptions = parcel.readBundle();

        if (mAdvancedOptions != null) {
            Preconditions.checkArgument(!mAdvancedOptions.containsKey(null));
        }
    }

    /**
     * Gets the unique print job id.
     *
     * @return The id.
     */
    public @Nullable PrintJobId getId() {
        return mId;
    }

    /**
     * Sets the unique print job id.
     *
     * @param id The job id.
     *
     * @hide
     */
    public void setId(@NonNull PrintJobId id) {
        this.mId = id;
    }

    /**
     * Gets the human readable job label.
     *
     * @return The label.
     */
    public @NonNull String getLabel() {
        return mLabel;
    }

    /**
     * Sets the human readable job label.
     *
     * @param label The label.
     *
     * @hide
     */
    public void setLabel(@NonNull String label) {
        mLabel = label;
    }

    /**
     * Gets the unique target printer id.
     *
     * @return The target printer id.
     */
    public @Nullable PrinterId getPrinterId() {
        return mPrinterId;
    }

    /**
     * Sets the unique target printer id.
     *
     * @param printerId The target printer id.
     *
     * @hide
     */
    public void setPrinterId(@NonNull PrinterId printerId) {
        mPrinterId = printerId;
    }

    /**
     * Gets the name of the target printer.
     *
     * @return The printer name.
     *
     * @hide
     */
    public @Nullable String getPrinterName() {
        return mPrinterName;
    }

    /**
     * Sets the name of the target printer.
     *
     * @param printerName The printer name.
     *
     * @hide
     */
    public void setPrinterName(@NonNull String printerName) {
        mPrinterName = printerName;
    }

    /**
     * Gets the current job state.
     *
     * @return The job state.
     *
     * @see #STATE_CREATED
     * @see #STATE_QUEUED
     * @see #STATE_STARTED
     * @see #STATE_COMPLETED
     * @see #STATE_BLOCKED
     * @see #STATE_FAILED
     * @see #STATE_CANCELED
     */
    public @State int getState() {
        return mState;
    }

    /**
     * Sets the current job state.
     *
     * @param state The job state.
     *
     * @hide
     */
    public void setState(int state) {
        mState = state;
    }

    /**
     * Sets the progress of the print job.
     *
     * @param progress the progress of the job
     *
     * @hide
     */
    public void setProgress(@FloatRange(from=0.0, to=1.0) float progress) {
        Preconditions.checkArgumentInRange(progress, 0, 1, "progress");

        mProgress = progress;
    }

    /**
     * Sets the status of the print job.
     *
     * @param status the status of the job, can be null
     *
     * @hide
     */
    public void setStatus(@Nullable CharSequence status) {
        mStatusRes = 0;
        mStatusResAppPackageName = null;

        mStatus = status;
    }

    /**
     * Sets the status of the print job.
     *
     * @param status The new status as a string resource
     * @param appPackageName App package name the resource belongs to
     *
     * @hide
     */
    public void setStatus(@StringRes int status, @NonNull CharSequence appPackageName) {
        mStatus = null;

        mStatusRes = status;
        mStatusResAppPackageName = appPackageName;
    }

    /**
     * Sets the owning application id.
     *
     * @return The owning app id.
     *
     * @hide
     */
    public int getAppId() {
        return mAppId;
    }

    /**
     * Sets the owning application id.
     *
     * @param appId The owning app id.
     *
     * @hide
     */
    public void setAppId(int appId) {
        mAppId = appId;
    }

    /**
     * Gets the optional tag assigned by a print service.
     *
     * @return The tag.
     *
     * @hide
     */
    public String getTag() {
        return mTag;
    }

    /**
     * Sets the optional tag assigned by a print service.
     *
     * @param tag The tag.
     *
     * @hide
     */
    public void setTag(String tag) {
        mTag = tag;
    }

    /**
     * Gets the wall time in millisecond when this print job was created.
     *
     * @return The creation time in milliseconds.
     */
    public long getCreationTime() {
        return mCreationTime;
    }

    /**
     * Sets the wall time in milliseconds when this print job was created.
     *
     * @param creationTime The creation time in milliseconds.
     *
     * @hide
     */
    public void setCreationTime(long creationTime) {
        if (creationTime < 0) {
            throw new IllegalArgumentException("creationTime must be non-negative.");
        }
        mCreationTime = creationTime;
    }

    /**
     * Gets the number of copies.
     *
     * @return The number of copies or zero if not set.
     */
    public @IntRange(from = 0) int getCopies() {
        return mCopies;
    }

    /**
     * Sets the number of copies.
     *
     * @param copyCount The number of copies.
     *
     * @hide
     */
    public void setCopies(int copyCount) {
        if (copyCount < 1) {
            throw new IllegalArgumentException("Copies must be more than one.");
        }
        mCopies = copyCount;
    }

    /**
     * Gets the included pages.
     *
     * @return The included pages or <code>null</code> if not set.
     */
    public @Nullable PageRange[] getPages() {
        return mPageRanges;
    }

    /**
     * Sets the included pages.
     *
     * @param pageRanges The included pages.
     *
     * @hide
     */
    public void setPages(PageRange[] pageRanges) {
        mPageRanges = pageRanges;
    }

    /**
     * Gets the print job attributes.
     *
     * @return The attributes.
     */
    public @NonNull PrintAttributes getAttributes() {
        return mAttributes;
    }

    /**
     * Sets the print job attributes.
     *
     * @param attributes The attributes.
     *
     * @hide
     */
    public void setAttributes(PrintAttributes attributes) {
        mAttributes = attributes;
    }

    /**
     * Gets the info describing the printed document.
     *
     * @return The document info.
     *
     * @hide
     */
    @UnsupportedAppUsage
    public PrintDocumentInfo getDocumentInfo() {
        return mDocumentInfo;
    }

    /**
     * Sets the info describing the printed document.
     *
     * @param info The document info.
     *
     * @hide
     */
    public void setDocumentInfo(PrintDocumentInfo info) {
        mDocumentInfo = info;
    }

    /**
     * Gets whether this print is being cancelled.
     *
     * @return True if the print job is being cancelled.
     *
     * @hide
     */
    public boolean isCancelling() {
        return mCanceling;
    }

    /**
     * Sets whether this print is being cancelled.
     *
     * @param cancelling True if the print job is being cancelled.
     *
     * @hide
     */
    public void setCancelling(boolean cancelling) {
        mCanceling = cancelling;
    }

    /**
     * If the print job is actively processed, i.e. the device needs to stay on.
     *
     * @hide
     */
    public boolean shouldStayAwake() {
        return mCanceling || mState == STATE_STARTED || mState == STATE_QUEUED;
    }

    /**
     * Gets whether this job has a given advanced (printer specific) print
     * option.
     *
     * @param key The option key.
     * @return Whether the option is present.
     */
    public boolean hasAdvancedOption(String key) {
        return mAdvancedOptions != null && mAdvancedOptions.containsKey(key);
    }

    /**
     * Gets the value of an advanced (printer specific) print option.
     *
     * @param key The option key.
     * @return The option value.
     */
    public String getAdvancedStringOption(String key) {
        if (mAdvancedOptions != null) {
            return mAdvancedOptions.getString(key);
        }
        return null;
    }

    /**
     * Gets the value of an advanced (printer specific) print option.
     *
     * @param key The option key.
     * @return The option value.
     */
    public int getAdvancedIntOption(String key) {
        if (mAdvancedOptions != null) {
            return mAdvancedOptions.getInt(key);
        }
        return 0;
    }

    /**
     * Gets the advanced options.
     *
     * @return The advanced options.
     *
     * @hide
     */
    @UnsupportedAppUsage
    public Bundle getAdvancedOptions() {
        return mAdvancedOptions;
    }

    /**
     * Sets the advanced options.
     *
     * @param options The advanced options.
     *
     * @hide
     */
    public void setAdvancedOptions(Bundle options) {
        mAdvancedOptions = options;
    }

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

    @Override
    public void writeToParcel(Parcel parcel, int flags) {
        parcel.writeParcelable(mId, flags);
        parcel.writeString(mLabel);
        parcel.writeParcelable(mPrinterId, flags);
        parcel.writeString(mPrinterName);
        parcel.writeInt(mState);
        parcel.writeInt(mAppId);
        parcel.writeString(mTag);
        parcel.writeLong(mCreationTime);
        parcel.writeInt(mCopies);
        parcel.writeParcelableArray(mPageRanges, flags);
        parcel.writeParcelable(mAttributes, flags);
        parcel.writeParcelable(mDocumentInfo, 0);
        parcel.writeFloat(mProgress);
        parcel.writeCharSequence(mStatus);
        parcel.writeInt(mStatusRes);
        parcel.writeCharSequence(mStatusResAppPackageName);
        parcel.writeInt(mCanceling ? 1 : 0);
        parcel.writeBundle(mAdvancedOptions);
    }

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        builder.append("PrintJobInfo{");
        builder.append("label: ").append(mLabel);
        builder.append(", id: ").append(mId);
        builder.append(", state: ").append(stateToString(mState));
        builder.append(", printer: " + mPrinterId);
        builder.append(", tag: ").append(mTag);
        builder.append(", creationTime: " + mCreationTime);
        builder.append(", copies: ").append(mCopies);
        builder.append(", attributes: " + (mAttributes != null
                ? mAttributes.toString() : null));
        builder.append(", documentInfo: " + (mDocumentInfo != null
                ? mDocumentInfo.toString() : null));
        builder.append(", cancelling: " + mCanceling);
        builder.append(", pages: " + (mPageRanges != null
                ? Arrays.toString(mPageRanges) : null));
        builder.append(", hasAdvancedOptions: " + (mAdvancedOptions != null));
        builder.append(", progress: " + mProgress);
        builder.append(", status: " + (mStatus != null
                ? mStatus.toString() : null));
        builder.append(", statusRes: " + mStatusRes);
        builder.append(", statusResAppPackageName: " + (mStatusResAppPackageName != null
                ? mStatusResAppPackageName.toString() : null));
        builder.append("}");
        return builder.toString();
    }

    /** @hide */
    public static String stateToString(int state) {
        switch (state) {
            case STATE_CREATED: {
                return "STATE_CREATED";
            }
            case STATE_QUEUED: {
                return "STATE_QUEUED";
            }
            case STATE_STARTED: {
                return "STATE_STARTED";
            }
            case STATE_BLOCKED: {
                return "STATE_BLOCKED";
            }
            case STATE_FAILED: {
                return "STATE_FAILED";
            }
            case STATE_COMPLETED: {
                return "STATE_COMPLETED";
            }
            case STATE_CANCELED: {
                return "STATE_CANCELED";
            }
            default: {
                return "STATE_UNKNOWN";
            }
        }
    }

    /**
     * Get the progress that has been made printing this job.
     *
     * @return the print progress or -1 if not set
     * @hide
     */
    @TestApi
    public float getProgress() {
        return mProgress;
    }

    /**
     * Get the status of this job.
     *
     * @param pm Package manager used to resolve the string
     *
     * @return the status of this job or null if not set
     * @hide
     */
    @TestApi
    public @Nullable CharSequence getStatus(@NonNull PackageManager pm) {
        if (mStatusRes == 0) {
            return mStatus;
        } else {
            try {
                return pm.getResourcesForApplication(mStatusResAppPackageName.toString())
                        .getString(mStatusRes);
            } catch (PackageManager.NameNotFoundException | Resources.NotFoundException e) {
                return null;
            }
        }
    }

    /**
     * Builder for creating a {@link PrintJobInfo}.
     */
    public static final class Builder {
        private final PrintJobInfo mPrototype;

        /**
         * Constructor.
         *
         * @param prototype Prototype to use as a starting point.
         * Can be <code>null</code>.
         */
        public Builder(@Nullable PrintJobInfo prototype) {
            mPrototype = (prototype != null)
                    ? new PrintJobInfo(prototype)
                    : new PrintJobInfo();
        }

        /**
         * Sets the number of copies.
         *
         * @param copies The number of copies.
         */
        public void setCopies(@IntRange(from = 1) int copies) {
            mPrototype.mCopies = copies;
        }

        /**
         * Sets the print job attributes.
         *
         * @param attributes The attributes.
         */
        public void setAttributes(@NonNull PrintAttributes attributes) {
            mPrototype.mAttributes = attributes;
        }

        /**
         * Sets the included pages.
         *
         * @param pages The included pages.
         */
        public void setPages(@NonNull PageRange[] pages) {
            mPrototype.mPageRanges = pages;
        }

        /**
         * Sets the progress of the print job.
         *
         * @param progress the progress of the job
         * @hide
         */
        public void setProgress(@FloatRange(from=0.0, to=1.0) float progress) {
            Preconditions.checkArgumentInRange(progress, 0, 1, "progress");

            mPrototype.mProgress = progress;
        }

        /**
         * Sets the status of the print job.
         *
         * @param status the status of the job, can be null
         * @hide
         */
        public void setStatus(@Nullable CharSequence status) {
            mPrototype.mStatus = status;
        }

        /**
         * Puts an advanced (printer specific) option.
         *
         * @param key The option key.
         * @param value The option value.
         */
        public void putAdvancedOption(@NonNull String key, @Nullable String value) {
            Preconditions.checkNotNull(key, "key cannot be null");

            if (mPrototype.mAdvancedOptions == null) {
                mPrototype.mAdvancedOptions = new Bundle();
            }
            mPrototype.mAdvancedOptions.putString(key, value);
        }

        /**
         * Puts an advanced (printer specific) option.
         *
         * @param key The option key.
         * @param value The option value.
         */
        public void putAdvancedOption(@NonNull String key, int value) {
            if (mPrototype.mAdvancedOptions == null) {
                mPrototype.mAdvancedOptions = new Bundle();
            }
            mPrototype.mAdvancedOptions.putInt(key, value);
        }

        /**
         * Creates a new {@link PrintJobInfo} instance.
         *
         * @return The new instance.
         */
        public @NonNull PrintJobInfo build() {
            return mPrototype;
        }
    }

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

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