// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package org.chromium.printing;

import android.annotation.TargetApi;
import android.os.Build;
import android.os.Bundle;
import android.os.CancellationSignal;
import android.os.ParcelFileDescriptor;
import android.print.PageRange;
import android.print.PrintAttributes;
import android.print.PrintDocumentInfo;

import org.chromium.base.Log;
import org.chromium.base.ThreadUtils;
import org.chromium.printing.PrintDocumentAdapterWrapper.PdfGenerator;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;

/**
 * Controls the interactions with Android framework related to printing.
 *
 * This class is singleton, since at any point at most one printing dialog can exist. Also, since
 * this dialog is modal, user can't interact with the browser unless they close the dialog or press
 * the print button. The singleton object lives in UI thread. Interaction with the native side is
 * carried through PrintingContext class.
 */
@TargetApi(Build.VERSION_CODES.KITKAT)
public class PrintingControllerImpl implements PrintingController, PdfGenerator {
    private static final String TAG = "printing";

    /**
     * This is used for both initial state and a completed state (i.e. starting from either
     * onLayout or onWrite, a PDF generation cycle is completed another new one can safely start).
     */
    private static final int PRINTING_STATE_READY = 0;
    private static final int PRINTING_STATE_STARTED_FROM_ONWRITE = 1;
    /** Printing dialog has been dismissed and cleanup has been done. */
    private static final int PRINTING_STATE_FINISHED = 2;

    /** The singleton instance for this class. */
    private static PrintingController sInstance;

    private final String mErrorMessage;

    private PrintingContextInterface mPrintingContext;

    /**
     * The context of a query initiated by window.print(), stored here to allow syncrhonization
     * with javascript.
     */
    private PrintingContextInterface mContextFromScriptInitiation;
    private int mRenderProcessId;
    private int mRenderFrameId;

    /** The file descriptor into which the PDF will be written.  Provided by the framework. */
    private int mFileDescriptor;

    /** Dots per inch, as provided by the framework. */
    private int mDpi;

    /** Paper dimensions. */
    private PrintAttributes.MediaSize mMediaSize;

    /** Numbers of pages to be printed, zero indexed. */
    private int[] mPages;

    /** The callback function to inform the result of PDF generation to the framework. */
    private PrintDocumentAdapterWrapper.WriteResultCallbackWrapper mOnWriteCallback;

    /**
     * The callback function to inform the result of layout to the framework.  We save the callback
     * because we start the native PDF generation process inside onLayout, and we need to pass the
     * number of expected pages back to the framework through this callback once the native side
     * has that information.
     */
    private PrintDocumentAdapterWrapper.LayoutResultCallbackWrapper mOnLayoutCallback;

    /** The object through which native PDF generation process is initiated. */
    private Printable mPrintable;

    /** The object through which the framework will make calls for generating PDF. */
    private PrintDocumentAdapterWrapper mPrintDocumentAdapterWrapper;

    private int mPrintingState = PRINTING_STATE_READY;

    private boolean mIsBusy;

    private PrintManagerDelegate mPrintManager;

    private PrintingControllerImpl(
            PrintDocumentAdapterWrapper printDocumentAdapterWrapper, String errorText) {
        mErrorMessage = errorText;
        mPrintDocumentAdapterWrapper = printDocumentAdapterWrapper;
        mPrintDocumentAdapterWrapper.setPdfGenerator(this);
    }

    /**
     * Creates a controller for handling printing with the framework.
     *
     * The controller is a singleton, since there can be only one printing action at any time.
     *
     * @param printDocumentAdapterWrapper The object through which the framework will make calls
     *                                    for generating PDF.
     * @param errorText The error message to be shown to user in case something goes wrong in PDF
     *                  generation in Chromium. We pass it here as a string so src/printing/android
     *                  doesn't need any string dependency.
     * @return The resulting PrintingController.
     */
    public static PrintingController create(
            PrintDocumentAdapterWrapper printDocumentAdapterWrapper, String errorText) {
        ThreadUtils.assertOnUiThread();

        if (sInstance == null) {
            sInstance = new PrintingControllerImpl(printDocumentAdapterWrapper, errorText);
        }
        return sInstance;
    }

    /**
     * Returns the singleton instance, created by the {@link PrintingControllerImpl#create}.
     *
     * This method must be called once {@link PrintingControllerImpl#create} is called, and always
     * thereafter.
     *
     * @return The singleton instance.
     */
    public static PrintingController getInstance() {
        return sInstance;
    }

    @Override
    public boolean hasPrintingFinished() {
        return mPrintingState == PRINTING_STATE_FINISHED;
    }

    @Override
    public int getDpi() {
        return mDpi;
    }

    @Override
    public int getFileDescriptor() {
        return mFileDescriptor;
    }

    @Override
    public int getPageHeight() {
        return mMediaSize.getHeightMils();
    }

    @Override
    public int getPageWidth() {
        return mMediaSize.getWidthMils();
    }

    @Override
    public int[] getPageNumbers() {
        return mPages == null ? null : mPages.clone();
    }

    @Override
    public boolean isBusy() {
        return mIsBusy;
    }

    @Override
    public void setPrintingContext(final PrintingContextInterface printingContext) {
        mPrintingContext = printingContext;
    }

    @Override
    public void setPendingPrint(final Printable printable, PrintManagerDelegate printManager,
            int renderProcessId, int renderFrameId) {
        if (mIsBusy) {
            Log.d(TAG, "Pending print can't be set. PrintingController is busy.");
            return;
        }
        mPrintable = printable;
        mPrintManager = printManager;
        mRenderProcessId = renderProcessId;
        mRenderFrameId = renderFrameId;
    }

    @Override
    public void startPendingPrint(PrintingContextInterface printingContext) {
        boolean canStartPrint = false;
        if (mIsBusy) {
            Log.d(TAG, "Pending print can't be started. PrintingController is busy.");
        } else if (mPrintManager == null) {
            Log.d(TAG, "Pending print can't be started. No PrintManager provided.");
        } else if (!mPrintable.canPrint()) {
            Log.d(TAG, "Pending print can't be started. Printable can't perform printing.");
        } else {
            canStartPrint = true;
        }

        if (!canStartPrint) {
            if (printingContext != null) printingContext.showSystemDialogDone();
            return;
        }

        mContextFromScriptInitiation = printingContext;
        mIsBusy = true;
        mPrintDocumentAdapterWrapper.print(mPrintManager, mPrintable.getTitle());
        mPrintManager = null;
    }

    @Override
    public void startPrint(final Printable printable, PrintManagerDelegate printManager) {
        if (mIsBusy) return;
        setPendingPrint(printable, printManager, mRenderProcessId, mRenderFrameId);
        startPendingPrint(null);
    }

    @Override
    public void pdfWritingDone(int pageCount) {
        if (mPrintingState == PRINTING_STATE_FINISHED) return;
        mPrintingState = PRINTING_STATE_READY;
        closeFileDescriptor(mFileDescriptor);
        mFileDescriptor = -1;
        if (pageCount > 0) {
            PageRange[] pageRanges = convertIntegerArrayToPageRanges(mPages, pageCount);
            mOnWriteCallback.onWriteFinished(pageRanges);
        } else {
            mOnWriteCallback.onWriteFailed(mErrorMessage);
            resetCallbacks();
        }
    }

    @Override
    public void onStart() {
        mPrintingState = PRINTING_STATE_READY;
    }

    @Override
    public void onLayout(
            PrintAttributes oldAttributes,
            PrintAttributes newAttributes,
            CancellationSignal cancellationSignal,
            PrintDocumentAdapterWrapper.LayoutResultCallbackWrapper callback,
            Bundle metadata) {
        // NOTE: Chrome printing just supports one DPI, whereas Android has both vertical and
        // horizontal.  These two values are most of the time same, so we just pass one of them.
        mDpi = newAttributes.getResolution().getHorizontalDpi();
        mMediaSize = newAttributes.getMediaSize();

        mOnLayoutCallback = callback;
        // We don't want to stack Chromium with multiple PDF generation operations before
        // completion of an ongoing one.
        if (mPrintingState == PRINTING_STATE_STARTED_FROM_ONWRITE) {
            callback.onLayoutFailed(mErrorMessage);
            resetCallbacks();
        } else {
            PrintDocumentInfo info =
                    new PrintDocumentInfo.Builder(mPrintable.getTitle())
                            .setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT)
                            // Set page count to unknown since Android framework will get it from
                            // PDF file generated in onWrite.
                            .setPageCount(PrintDocumentInfo.PAGE_COUNT_UNKNOWN)
                            .build();
            // We always need to generate a new PDF. onLayout is not only called when attributes
            // changed, but also when pages need to print got selected. We can't tell if the later
            // case was happened, so has to generate a new file.
            mOnLayoutCallback.onLayoutFinished(info, true);
        }
    }

    @Override
    public void onWrite(
            final PageRange[] ranges,
            final ParcelFileDescriptor destination,
            final CancellationSignal cancellationSignal,
            final PrintDocumentAdapterWrapper.WriteResultCallbackWrapper callback) {
        // TODO(cimamoglu): Make use of CancellationSignal.
        if (ranges == null || ranges.length == 0) {
            callback.onWriteFailed(null);
            return;
        }

        mOnWriteCallback = callback;

        assert mPrintingState == PRINTING_STATE_READY;

        mFileDescriptor = destination.getFd();
        mPages = convertPageRangesToIntegerArray(ranges);

        // mRenderProcessId and mRenderFrameId could be invalid values, in this case we are going to
        // print the main frame.
        if (mPrintable.print(mRenderProcessId, mRenderFrameId)) {
            mPrintingState = PRINTING_STATE_STARTED_FROM_ONWRITE;
        } else {
            mOnWriteCallback.onWriteFailed(mErrorMessage);
            resetCallbacks();
        }
        // We are guaranteed by the framework that we will not have two onWrite calls at once.
        // We may get a CancellationSignal, after replying it (via WriteResultCallback) we might
        // get another onWrite call.
    }

    @Override
    public void onFinish() {
        mPages = null;
        if (mPrintingContext != null) {
            if (mPrintingState != PRINTING_STATE_READY) {
                // Note that we are never making an extraneous askUserForSettingsReply call.
                // If we are in the middle of a PDF generation from onLayout or onWrite, it means
                // the state isn't PRINTING_STATE_READY, so we enter here and make this call (no
                // extra). If we complete the PDF generation successfully from onLayout or onWrite,
                // we already make the state PRINTING_STATE_READY and call askUserForSettingsReply
                // inside pdfWritingDone, thus not entering here.
                mPrintingContext.askUserForSettingsReply(false);
            }
            mPrintingContext.updatePrintingContextMap(mFileDescriptor, true);
            mPrintingContext = null;
        }

        if (mContextFromScriptInitiation != null) {
            mContextFromScriptInitiation.showSystemDialogDone();
            mContextFromScriptInitiation = null;
        }
        mRenderProcessId = -1;
        mRenderFrameId = -1;

        mPrintingState = PRINTING_STATE_FINISHED;

        closeFileDescriptor(mFileDescriptor);
        mFileDescriptor = -1;

        resetCallbacks();
        // The printmanager contract is that onFinish() is always called as the last
        // callback. We set busy to false here.
        mIsBusy = false;
    }

    private void resetCallbacks() {
        mOnWriteCallback = null;
        mOnLayoutCallback = null;
    }

    private static void closeFileDescriptor(int fd) {
        ParcelFileDescriptor fileDescriptor = ParcelFileDescriptor.adoptFd(fd);
        try {
            fileDescriptor.close();
        } catch (IOException ioe) {
            /* ignore */
        }
    }

    private static PageRange[] convertIntegerArrayToPageRanges(int[] pagesArray, int pageCount) {
        PageRange[] pageRanges;
        if (pagesArray != null) {
            pageRanges = new PageRange[pagesArray.length];
            for (int i = 0; i < pageRanges.length; i++) {
                int page = pagesArray[i];
                pageRanges[i] = new PageRange(page, page);
            }
        } else {
            // null corresponds to all pages in Chromium printing logic.
            pageRanges = new PageRange[] {new PageRange(0, pageCount - 1)};
        }
        return pageRanges;
    }

    /**
     * Gets an array of page ranges and returns an array of integers with all ranges expanded.
     */
    private static int[] convertPageRangesToIntegerArray(final PageRange[] ranges) {
        if (ranges.length == 1 && ranges[0].equals(PageRange.ALL_PAGES)) {
            // null corresponds to all pages in Chromium printing logic.
            return null;
        }

        // Expand ranges into a list of individual numbers.
        ArrayList<Integer> pages = new ArrayList<Integer>();
        for (PageRange range : ranges) {
            for (int i = range.getStart(); i <= range.getEnd(); i++) {
                pages.add(i);
            }
        }

        // Convert the list into array.
        int[] ret = new int[pages.size()];
        Iterator<Integer> iterator = pages.iterator();
        for (int i = 0; i < ret.length; i++) {
            ret[i] = iterator.next().intValue();
        }
        return ret;
    }
}
