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

import static android.print.test.Utils.eventually;

import android.os.ParcelFileDescriptor;
import android.platform.test.annotations.AppModeFull;
import android.print.PageRange;
import android.print.PrintAttributes;
import android.print.PrintAttributes.Margins;
import android.print.PrintAttributes.MediaSize;
import android.print.PrintAttributes.Resolution;
import android.print.PrintDocumentAdapter;
import android.print.PrintDocumentAdapter.LayoutResultCallback;
import android.print.PrintDocumentAdapter.WriteResultCallback;
import android.print.PrintDocumentInfo;
import android.print.PrintJobInfo;
import android.print.PrinterCapabilitiesInfo;
import android.print.PrinterId;
import android.print.PrinterInfo;
import android.print.test.BasePrintTest;
import android.print.test.services.CustomPrintOptionsActivity;
import android.print.test.services.FirstPrintService;
import android.print.test.services.PrintServiceCallbacks;
import android.print.test.services.PrinterDiscoverySessionCallbacks;
import android.print.test.services.SecondPrintService;
import android.print.test.services.StubbablePrinterDiscoverySession;
import android.support.test.runner.AndroidJUnit4;
import android.support.test.uiautomator.By;
import android.support.test.uiautomator.UiObject;
import android.support.test.uiautomator.UiObjectNotFoundException;
import android.support.test.uiautomator.UiSelector;
import android.util.Log;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeoutException;

/**
 * This test verifies changes to the printer capabilities are applied correctly.
 */
@AppModeFull(reason = "Print UI cannot resolve custom print options activity in a instant app")
@RunWith(AndroidJUnit4.class)
public class CustomPrintOptionsTest extends BasePrintTest {
    private final static String LOG_TAG = "CustomPrintOptionsTest";
    private static final String PRINTER_NAME = "Test printer";
    private static final int MAX_TRIES = 10;

    // Default settings
    private final PageRange[] DEFAULT_PAGES = new PageRange[] { new PageRange(0, 0) };
    private final MediaSize DEFAULT_MEDIA_SIZE = MediaSize.ISO_A0;
    private final int DEFAULT_COLOR_MODE = PrintAttributes.COLOR_MODE_COLOR;
    private final int DEFAULT_DUPLEX_MODE = PrintAttributes.DUPLEX_MODE_LONG_EDGE;
    private final Resolution DEFAULT_RESOLUTION = new Resolution("300x300", "300x300", 300, 300);
    private final Margins DEFAULT_MARGINS = new Margins(0, 0, 0, 0);

    // All settings that are tested
    private final PageRange[][] PAGESS = { DEFAULT_PAGES, new PageRange[] { new PageRange(1, 1) },
            new PageRange[] { new PageRange(0, 2) }
    };
    private final MediaSize[] MEDIA_SIZES = { DEFAULT_MEDIA_SIZE, MediaSize.ISO_B0 };
    private final Integer[] COLOR_MODES = { DEFAULT_COLOR_MODE,
            PrintAttributes.COLOR_MODE_MONOCHROME
    };
    private final Integer[] DUPLEX_MODES = { DEFAULT_DUPLEX_MODE, PrintAttributes.DUPLEX_MODE_NONE
    };
    private final Resolution[] RESOLUTIONS = { DEFAULT_RESOLUTION,
            new Resolution("600x600", "600x600", 600, 600)
    };

    private PrintAttributes mLayoutAttributes;
    private PrintDocumentAdapter mAdapter;
    private static boolean sHasDefaultPrinterSet;

    /**
     * Get the page ranges currently selected as described in the UI.
     *
     * @return Only page ranges from {@link #PAGESS} are detected correctly.
     *
     * @throws Exception If something was unexpected
     */
    private PageRange[] getPages() throws Exception {
        if (getUiDevice().hasObject(By.text("All 3"))) {
            return PAGESS[2];
        }

        try {
            UiObject pagesEditText = getUiDevice().findObject(new UiSelector().resourceId(
                    "com.android.printspooler:id/page_range_edittext"));

            if (pagesEditText.getText().equals("2")) {
                return PAGESS[1];
            }

            if (pagesEditText.getText().equals("1")) {
                return PAGESS[0];
            }

            return null;
        } catch (UiObjectNotFoundException e) {
            dumpWindowHierarchy();
            throw e;
        }
    }

    @Before
    public void setUpServicesAndAdapter() {
        final PrinterDiscoverySessionCallbacks firstSessionCallbacks =
                createMockPrinterDiscoverySessionCallbacks(invocation -> {
                    StubbablePrinterDiscoverySession session =
                            ((PrinterDiscoverySessionCallbacks) invocation.getMock())
                                    .getSession();
                    PrinterId printerId = session.getService().generatePrinterId(PRINTER_NAME);
                    List<PrinterInfo> printers = new ArrayList<>(1);
                    PrinterCapabilitiesInfo.Builder builder =
                            new PrinterCapabilitiesInfo.Builder(printerId);

                    builder.setMinMargins(DEFAULT_MARGINS)
                            .setColorModes(COLOR_MODES[0] | COLOR_MODES[1],
                                    DEFAULT_COLOR_MODE)
                            .setDuplexModes(DUPLEX_MODES[0] | DUPLEX_MODES[1],
                                    DEFAULT_DUPLEX_MODE)
                            .addMediaSize(DEFAULT_MEDIA_SIZE, true)
                            .addMediaSize(MEDIA_SIZES[1], false)
                            .addResolution(DEFAULT_RESOLUTION, true)
                            .addResolution(RESOLUTIONS[1], false);

                    printers.add(new PrinterInfo.Builder(printerId, PRINTER_NAME,
                            PrinterInfo.STATUS_IDLE).setCapabilities(builder.build()).build());

                    session.addPrinters(printers);
                    return null;
                }, null, null, null, null, null, invocation -> {
                    onPrinterDiscoverySessionDestroyCalled();
                    return null;
                });

        mAdapter = createMockPrintDocumentAdapter(
                invocation -> {
                    LayoutResultCallback callback = (LayoutResultCallback) invocation
                            .getArguments()[3];
                    PrintDocumentInfo info = new PrintDocumentInfo.Builder(PRINT_JOB_NAME)
                            .setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT)
                            .setPageCount(3)
                            .build();

                    synchronized (CustomPrintOptionsTest.this) {
                        mLayoutAttributes = (PrintAttributes) invocation.getArguments()[1];

                        CustomPrintOptionsTest.this.notifyAll();
                    }

                    callback.onLayoutFinished(info, true);
                    return null;
                },
                invocation -> {
                    Object[] args = invocation.getArguments();
                    ParcelFileDescriptor fd = (ParcelFileDescriptor) args[1];
                    WriteResultCallback callback = (WriteResultCallback) args[3];

                    PageRange[] writtenPages = (PageRange[]) args[0];

                    writeBlankPages(mLayoutAttributes, fd, writtenPages[0].getStart(),
                            writtenPages[0].getEnd());
                    fd.close();

                    callback.onWriteFinished(writtenPages);

                    onWriteCalled();

                    return null;
                }, null);

        // Create the service callbacks for the first print service.
        PrintServiceCallbacks firstServiceCallbacks = createMockPrintServiceCallbacks(
                invocation -> firstSessionCallbacks, null, null);

        // Configure the print services.
        FirstPrintService.setCallbacks(firstServiceCallbacks);
        SecondPrintService.setCallbacks(createMockPrintServiceCallbacks(null, null, null));

        // Set default printer
        if (!sHasDefaultPrinterSet) {
            // This is the first print test that runs. If this is run after other tests these other
            // test can still cause memory pressure and make the printactivity to go through a
            // destroy-create cycle. In this case we have to retry to operation.
            int tries = 0;
            while (true) {
                try {
                    resetCounters();
                    makeDefaultPrinter(mAdapter, PRINTER_NAME);
                    break;
                } catch (Throwable e) {
                    if (getActivityDestroyCallbackCallCount() > 0 && tries < MAX_TRIES) {
                        Log.e(LOG_TAG, "Activity was destroyed during test, retrying", e);

                        tries++;
                        continue;
                    }

                    throw new RuntimeException(e);
                }
            }

            sHasDefaultPrinterSet = true;
        }
    }

    /**
     * Test that we can switch to a specific set of settings via the custom print options activity
     *
     * @param copyFromOriginal If the print job info should be copied from the original
     * @param numCopies        The copies to print
     * @param pages            The page ranges to print
     * @param mediaSize        The media size to use
     * @param isPortrait       If the mediaSize is portrait
     * @param colorMode        The color mode to use
     * @param duplexMode       The duplex mode to use
     * @param resolution       The resolution to use
     *
     * @throws Exception If anything is unexpected
     */
    private void testCase(final boolean copyFromOriginal, final Integer numCopies,
            final PageRange[] pages, final MediaSize mediaSize, final boolean isPortrait,
            final Integer colorMode, final Integer duplexMode, final Resolution resolution)
            throws Throwable {
        final PrintAttributes.Builder additionalAttributesBuilder = new PrintAttributes.Builder();
        final PrintAttributes.Builder newAttributesBuilder = new PrintAttributes.Builder();

        newAttributesBuilder.setMinMargins(DEFAULT_MARGINS);

        if (mediaSize != null) {
            if (isPortrait) {
                additionalAttributesBuilder.setMediaSize(mediaSize.asPortrait());
                newAttributesBuilder.setMediaSize(mediaSize.asPortrait());
            } else {
                additionalAttributesBuilder.setMediaSize(mediaSize.asLandscape());
                newAttributesBuilder.setMediaSize(mediaSize.asLandscape());
            }
        } else {
            newAttributesBuilder.setMediaSize(DEFAULT_MEDIA_SIZE);
        }

        if (colorMode != null) {
            additionalAttributesBuilder.setColorMode(colorMode);
            newAttributesBuilder.setColorMode(colorMode);
        } else {
            newAttributesBuilder.setColorMode(DEFAULT_COLOR_MODE);
        }

        if (duplexMode != null) {
            additionalAttributesBuilder.setDuplexMode(duplexMode);
            newAttributesBuilder.setDuplexMode(duplexMode);
        } else {
            newAttributesBuilder.setDuplexMode(DEFAULT_DUPLEX_MODE);
        }

        if (resolution != null) {
            additionalAttributesBuilder.setResolution(resolution);
            newAttributesBuilder.setResolution(resolution);
        } else {
            newAttributesBuilder.setResolution(DEFAULT_RESOLUTION);
        }

        CustomPrintOptionsActivity.setCallBack(
                (printJob, printer) -> {
                    PrintJobInfo.Builder printJobBuilder;

                    if (copyFromOriginal) {
                        printJobBuilder = new PrintJobInfo.Builder(printJob);
                    } else {
                        printJobBuilder = new PrintJobInfo.Builder(null);
                    }

                    if (numCopies != null) {
                        printJobBuilder.setCopies(numCopies);
                    }

                    if (pages != null) {
                        printJobBuilder.setPages(pages);
                    }

                    if (mediaSize != null || colorMode != null || duplexMode != null
                            || resolution != null) {
                        printJobBuilder.setAttributes(additionalAttributesBuilder.build());
                    }

                    return printJobBuilder.build();
                });

        // Check that the attributes were send to the print service
        PrintAttributes newAttributes = newAttributesBuilder.build();
        Log.i(LOG_TAG, "Change to attributes: " + newAttributes + ", copies: " + numCopies +
                ", pages: " + Arrays.toString(pages) + ", copyFromOriginal: " + copyFromOriginal);

        // This is the first print test that runs. If this is run after other tests these other test
        // can still cause memory pressure and make the printactivity to go through a destroy-create
        // cycle. In this case we have to retry to operation.
        int tries = 0;
        while (true) {
            try {
                resetCounters();

                // Start printing
                print(mAdapter);

                // Wait for write.
                waitForWriteAdapterCallback(1);

                // Open the print options.
                openPrintOptions();

                // Apply options by executing callback above
                Log.d(LOG_TAG, "Apply changes");
                openCustomPrintOptions();

                Log.d(LOG_TAG, "Check attributes");
                long endTime = System.currentTimeMillis() + OPERATION_TIMEOUT_MILLIS;
                synchronized (this) {
                    while (mLayoutAttributes == null ||
                            !mLayoutAttributes.equals(newAttributes)) {
                        wait(Math.max(1, endTime - System.currentTimeMillis()));

                        if (endTime < System.currentTimeMillis()) {
                            throw new TimeoutException(
                                    "Print attributes did not change to " + newAttributes + " in " +
                                            OPERATION_TIMEOUT_MILLIS + " ms. Current attributes"
                                            + mLayoutAttributes);
                        }
                    }
                }

                PageRange[] newPages;

                if (pages == null) {
                    newPages = new PageRange[] { new PageRange(0, 2) };
                } else {
                    newPages = pages;
                }

                Log.d(LOG_TAG, "Check pages");
                eventually(() -> {
                    PageRange[] actualPages = getPages();
                    if (!Arrays.equals(newPages, actualPages)) {
                        throw new AssertionError(
                                "Expected " + Arrays.toString(newPages) + ", actual " +
                                        Arrays.toString(actualPages));
                    }
                });

                break;
            } catch (Throwable e) {
                if (getActivityDestroyCallbackCallCount() > 0 && tries < MAX_TRIES) {
                    Log.e(LOG_TAG, "Activity was destroyed during test, retrying", e);

                    tries++;
                    continue;
                }

                throw e;
            }
        }

        // Abort printing
        getUiDevice().pressBack();
        getUiDevice().pressBack();
        getUiDevice().pressBack();

        waitForPrinterDiscoverySessionDestroyCallbackCalled(1);
    }

    @Test
    public void changeToChangeEveryThingButPages() throws Throwable {
        testCase(false, 2, null, MEDIA_SIZES[1], false, COLOR_MODES[1], DUPLEX_MODES[1],
                RESOLUTIONS[1]);
    }

    @Test
    public void changeToAttributes() throws Throwable {
        testCase(false, null, null, MEDIA_SIZES[1], false, COLOR_MODES[1], DUPLEX_MODES[1],
                RESOLUTIONS[1]);
    }

    @Test
    public void changeToNonAttributes() throws Throwable {
        testCase(false, 2, PAGESS[1], null, true, null, null, null);
    }

    @Test
    public void changeToAttributesNoCopy() throws Throwable {
        testCase(true, null, null, MEDIA_SIZES[1], false, COLOR_MODES[1], DUPLEX_MODES[1],
                RESOLUTIONS[1]);
    }

    @Test
    public void changeToNonAttributesNoCopy() throws Throwable {
        testCase(true, 2, PAGESS[1], null, true, null, null, null);
    }

    @Test
    public void changeToDefault() throws Throwable {
        testCase(false, 1, DEFAULT_PAGES, DEFAULT_MEDIA_SIZE, DEFAULT_MEDIA_SIZE.isPortrait(),
                DEFAULT_COLOR_MODE, DEFAULT_DUPLEX_MODE, DEFAULT_RESOLUTION);
    }

    @Test
    public void changeToDefaultNoCopy() throws Throwable {
        testCase(true, 1, DEFAULT_PAGES, DEFAULT_MEDIA_SIZE, DEFAULT_MEDIA_SIZE.isPortrait(),
                DEFAULT_COLOR_MODE, DEFAULT_DUPLEX_MODE, DEFAULT_RESOLUTION);
    }

    @Test
    public void changeToNothing() throws Throwable {
        testCase(false, null, null, null, true, null, null, null);
    }

    @Test
    public void testChangeToNothingNoCopy() throws Throwable {
        testCase(true, null, null, null, true, null, null, null);
    }

    @Test
    public void changeToAllPages() throws Throwable {
        testCase(false, null, PAGESS[2], null, true, null, null, null);
    }

    @Test
    public void changeToSomePages() throws Throwable {
        testCase(false, null, PAGESS[1], null, true, null, null, null);
    }
}
