/*
 * Copyright (C) 2015 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 com.android.sysapp.janktests;

import android.os.RemoteException;
import android.os.SystemClock;
import android.support.test.jank.GfxMonitor;
import android.support.test.jank.JankTest;
import android.support.test.jank.JankTestBase;
import android.support.test.launcherhelper.ILauncherStrategy;
import android.support.test.launcherhelper.LauncherStrategyFactory;
import android.support.test.uiautomator.By;
import android.support.test.uiautomator.Direction;
import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.UiObject2;
import android.support.test.uiautomator.UiObjectNotFoundException;
import android.support.test.uiautomator.Until;
import android.widget.Button;
import android.widget.ProgressBar;

import junit.framework.Assert;

/**
 * Jank test for Books app recommendation page fling
 */

public class BooksJankTests extends JankTestBase {
    private static final int LONG_TIMEOUT = 1000;
    private static final int SHORT_TIMEOUT = 1000;
    private static final int INNER_LOOP = 5;
    private static final int EXPECTED_FRAMES = 100;
    private static final String PACKAGE_NAME = "com.google.android.apps.books";
    private static final String APP_NAME = "Play Books";
    private UiDevice mDevice;
    private ILauncherStrategy mLauncherStrategy = null;

    @Override
    public void setUp() throws Exception {
        super.setUp();
        mDevice = UiDevice.getInstance(getInstrumentation());
        try {
            mDevice.setOrientationNatural();
        } catch (RemoteException e) {
            throw new RuntimeException("failed to freeze device orientaion", e);
        }
        mLauncherStrategy = LauncherStrategyFactory.getInstance(mDevice).getLauncherStrategy();
    }

    @Override
    protected void tearDown() throws Exception {
        mDevice.unfreezeRotation();
        super.tearDown();
    }

    public void launchBooks () throws UiObjectNotFoundException {
        mLauncherStrategy.launch(APP_NAME, PACKAGE_NAME);
        dismissClings();
        openMyLibrary();
        Assert.assertTrue("Books haven't loaded yet", getNumberOfVisibleBooks() > 3);
    }

    // Measures jank while fling books mylibrary
    @JankTest(beforeTest="launchBooks", expectedFrames=EXPECTED_FRAMES)
    @GfxMonitor(processName=PACKAGE_NAME)
    public void testBooksRecommendationPageFling() {
        UiObject2 container = mDevice.wait(Until.findObject(
                By.res(PACKAGE_NAME, "content_container")), LONG_TIMEOUT);
        for (int i = 0; i < INNER_LOOP; i++) {
          container.scroll(Direction.DOWN, 1.0f);
          SystemClock.sleep(SHORT_TIMEOUT);
          container.scroll(Direction.UP, 1.0f);
        }
    }

    // All helper methods are at bottom
    // with the assumptions is that these will have their own library
    private void dismissClings() {
        // Dismiss confidentiality warning. It's okay to timeout here.
        UiObject2 warning = mDevice.wait(
                Until.findObject(By.clazz(".Button").text("OK")), LONG_TIMEOUT);
        if (warning != null) {
            warning. click();
        }
        // Close the drawer.
        UiObject2 close = mDevice.wait(
                Until.findObject(By.desc("Hide navigation drawer")), LONG_TIMEOUT);
        if (close != null) {
            close.click();
        }
        // Turn sync off
        UiObject2 syncoff = mDevice.wait(Until.findObject(
                By.clazz(Button.class).text("Keep sync off")), LONG_TIMEOUT);
        if (syncoff != null) {
            syncoff.click();
        }
    }

    public void openNavigationDrawer() {
      if (!mDevice.hasObject(By.res(PACKAGE_NAME, "play_drawer_container"))) {
          mDevice.findObject(By.desc("Show navigation drawer")).click();
          Assert.assertTrue("Failed to open navigation drawer", mDevice.wait(
              Until.hasObject(By.res(PACKAGE_NAME, "play_drawer_list")), LONG_TIMEOUT));

          // Extra sleep to wait for the drawer to finish sliding in
          SystemClock.sleep(500);
      }
  }

    public void openMyLibrary() {
        openNavigationDrawer();
        UiObject2 library = mDevice.wait(
            Until.findObject(By.text("My Library")), LONG_TIMEOUT);
        Assert.assertNotNull("Could not find 'My Library' button", library);
        library.click();
    }

    public int getNumberOfVisibleBooks() {
      UiObject2 list = mDevice.wait(
              Until.findObject(By.res(PACKAGE_NAME, "cards_grid")), LONG_TIMEOUT);
      Assert.assertNotNull("Failed to locate 'cards_grid'", list);
      return list.getChildCount();
    }
}
