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

import android.app.Activity;
import android.app.Instrumentation;
import android.app.UiAutomation;
import android.app.UiModeManager;
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.os.SystemClock;
import android.support.test.InstrumentationRegistry;
import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.UiObject;
import android.support.test.uiautomator.UiObjectNotFoundException;
import android.support.test.uiautomator.UiScrollable;
import android.support.test.uiautomator.UiSelector;

import com.android.compatibility.common.util.SystemUtil;

import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Collection of helper utils for testing preferences.
 */
public class TestUtils {

    final UiDevice device;
    private final Instrumentation mInstrumentation;
    private final UiAutomation mAutomation;
    private int mStatusBarHeight = -1;
    private int mNavigationBarHeight = -1;

    TestUtils() {
        mInstrumentation = InstrumentationRegistry.getInstrumentation();
        device = UiDevice.getInstance(mInstrumentation);
        mAutomation = mInstrumentation.getUiAutomation();
    }

    Bitmap takeScreenshot() {
        // Only take screenshot once the screen is stable enough.
        device.waitForIdle();

        Bitmap bt = mAutomation.takeScreenshot();

        // Crop-out the status bar to avoid flakiness with changing notifications / time.
        int statusBarHeight = getStatusBarHeight();

        // Crop-out the navigation bar to avoid flakiness with button animations.
        int navigationBarHeight = getNavigationBarHeight();

        // Crop the right side for scrollbar which might or might not be visible. On wearable
        // devices the scroll bar is a curve and occupies 20% of the right side.
        int xToCut = isOnWatchUiMode() ? bt.getWidth() / 5 : bt.getWidth() / 20;
        int yToCut = statusBarHeight;

        if (isLandscape()) {
            xToCut += navigationBarHeight;
        } else {
            yToCut += navigationBarHeight;
        }

        bt = Bitmap.createBitmap(
                bt, 0, statusBarHeight, bt.getWidth() - xToCut, bt.getHeight() - yToCut);

        return bt;
    }

    void tapOnViewWithText(String searchText) {
        if (searchText == null) {
            return;
        }

        try {
            // If the current UI has shown text, just click on it.
            UiObject text = new UiObject(new UiSelector().text(searchText));
            if (text.exists() || text.waitForExists(1000)) {
                text.click();
                return;
            }

            // Otherwise, if it is scrollable, scroll to where the text is and tap.
            UiScrollable textScroll = new UiScrollable(new UiSelector().scrollable(true));

            textScroll.scrollIntoView(new UiSelector().text(searchText));
            text = new UiObject(new UiSelector().text(searchText));
            text.click();
        } catch (UiObjectNotFoundException e) {
            throw new AssertionError("View with text '" + searchText + "' was not found!", e);
        }
    }

    boolean isTextShown(String searchText) {
        if (searchText == null) {
            return false;
        }

        UiObject text = new UiObject(new UiSelector().text(searchText));
        if (text.exists() || text.waitForExists(1000)) {
            return true;
        }

        UiScrollable textScroll = new UiScrollable(new UiSelector().scrollable(true));
        try {
            return textScroll.scrollIntoView(new UiSelector().text(searchText));
        } catch (UiObjectNotFoundException e) {
            return false;
        }
    }

    boolean isTextHidden(String text) {
        UiObject obj = device.findObject(new UiSelector().textMatches(text));
        if (!obj.exists()) {
            return true;
        }
        return obj.waitUntilGone(1000);
    }

    boolean isTextFocused(String text) {
        UiObject obj = device.findObject(new UiSelector().textMatches(text));
        try {
            return obj.isFocused();
        } catch (UiObjectNotFoundException e) {
            return false;
        }
    }

    boolean isOnWatchUiMode() {
        Context context = mInstrumentation.getTargetContext();
        UiModeManager uiModeManager = context.getSystemService(UiModeManager.class);
        return uiModeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_WATCH;
    }

    void getMultiWindowFocus(Context context) {
        // Get window focus (otherwise back press would close multi-window instead of firing to the
        // Activity and also the automator would fail to find objects on the screen.
        // We want to click slightly below status bar in the 1/3 of width of the screen.
        int x = device.getDisplayWidth() / 3;
        int resourceId =
                context.getResources().getIdentifier("status_bar_height", "dimen", "android");
        int statusBarHeight =
                (resourceId > 0) ? context.getResources().getDimensionPixelSize(resourceId) : 0;
        device.click(x, 2 * statusBarHeight);
    }

    // Multi-window helpers taken from ActivityManagerDockedStackTests.java

    void enterMultiWindow(Activity activity) {
        try {
            int id = getActivityTaskId(activity);
            runShellCommand("am stack move-task " + id + " 3 true");
        } catch (IOException e) {
            throw new RuntimeException("Failed to get activity task id!", e);
        }
        SystemClock.sleep(5000);
    }

    void leaveMultiWindow(Activity activity) {
        try {
            int id = getActivityTaskId(activity);
            runShellCommand("am stack move-task " + id + " 1 true");
        } catch (IOException e) {
            throw new RuntimeException("Failed to get activity task id!", e);
        }
        SystemClock.sleep(5000);
    }

    private int getActivityTaskId(Activity activity) throws IOException {
        // Taken from ActivityManagerTestBase.java
        final String output = runShellCommand("am stack list");
        final Pattern activityPattern =
                Pattern.compile("(.*) " + getWindowName(activity) + " (.*)");
        for (String line : output.split("\\n")) {
            Matcher matcher = activityPattern.matcher(line);
            if (matcher.matches()) {
                for (String word : line.split("\\s+")) {
                    if (word.startsWith("taskId")) {
                        final String withColon = word.split("=")[1];
                        return Integer.parseInt(withColon.substring(0, withColon.length() - 1));
                    }
                }
            }
        }
        return -1;
    }

    private String getWindowName(Activity activity) {
        String componentName = activity.getPackageName();
        String baseWindowName = componentName + "/" + componentName + ".";
        return baseWindowName + activity.getClass().getSimpleName();
    }

    private int getStatusBarHeight() {
        // Cache the result to keep it fast.
        if (mStatusBarHeight >= 0) {
            return mStatusBarHeight;
        }

        mStatusBarHeight = 0;
        int resourceId = mInstrumentation.getTargetContext().getResources()
                .getIdentifier("status_bar_height", "dimen", "android");
        if (resourceId > 0) {
            mStatusBarHeight = mInstrumentation.getTargetContext().getResources()
                    .getDimensionPixelSize(resourceId);
        }
        return mStatusBarHeight;
    }

    private int getNavigationBarHeight() {
        // Cache the result to keep it fast.
        if (mNavigationBarHeight >= 0) {
            return mNavigationBarHeight;
        }

        mNavigationBarHeight = 0;
        int resourceId = mInstrumentation.getTargetContext().getResources()
                .getIdentifier("navigation_bar_height", "dimen", "android");
        if (resourceId > 0) {
            mNavigationBarHeight = mInstrumentation.getTargetContext().getResources()
                    .getDimensionPixelSize(resourceId);
        }
        return mNavigationBarHeight;
    }

    private String runShellCommand(String cmd) {
        try {
            return SystemUtil.runShellCommand(mInstrumentation, cmd);
        } catch (IOException e) {
            throw new RuntimeException("Failed to run command: " + cmd, e);
        }
    }

    private boolean isLandscape() {
        return mInstrumentation.getTargetContext().getResources().getConfiguration().orientation ==
                Configuration.ORIENTATION_LANDSCAPE;
    }
}
