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

package org.chromium.chrome.features.start_surface;

import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.assertion.ViewAssertions.matches;
import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
import static androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility;
import static androidx.test.espresso.matcher.ViewMatchers.withId;

import static org.hamcrest.CoreMatchers.allOf;
import static org.hamcrest.CoreMatchers.not;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import static org.chromium.chrome.browser.tabmodel.TestTabModelDirectory.M26_GOOGLE_COM;
import static org.chromium.ui.test.util.ViewUtils.onViewWaiting;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.util.Base64;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.Nullable;
import androidx.test.espresso.UiController;
import androidx.test.espresso.ViewAction;
import androidx.test.espresso.matcher.ViewMatchers;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.uiautomator.UiDevice;

import org.hamcrest.Matcher;
import org.hamcrest.Matchers;
import org.junit.Assert;

import org.chromium.base.CommandLine;
import org.chromium.base.ContextUtils;
import org.chromium.base.StreamUtil;
import org.chromium.base.library_loader.LibraryLoader;
import org.chromium.base.test.params.ParameterProvider;
import org.chromium.base.test.params.ParameterSet;
import org.chromium.base.test.util.CallbackHelper;
import org.chromium.base.test.util.Criteria;
import org.chromium.base.test.util.CriteriaHelper;
import org.chromium.chrome.browser.ChromeTabbedActivity;
import org.chromium.chrome.browser.browser_controls.BrowserControlsStateProvider;
import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager;
import org.chromium.chrome.browser.flags.ChromeFeatureList;
import org.chromium.chrome.browser.flags.ChromeSwitches;
import org.chromium.chrome.browser.gesturenav.GestureNavigationUtils;
import org.chromium.chrome.browser.init.AsyncInitializationActivity;
import org.chromium.chrome.browser.layouts.LayoutTestUtils;
import org.chromium.chrome.browser.layouts.LayoutType;
import org.chromium.chrome.browser.suggestions.SiteSuggestion;
import org.chromium.chrome.browser.suggestions.tile.TileSectionType;
import org.chromium.chrome.browser.suggestions.tile.TileSource;
import org.chromium.chrome.browser.suggestions.tile.TileTitleSource;
import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.tab.TabState;
import org.chromium.chrome.browser.tab.TabUtils;
import org.chromium.chrome.browser.tabmodel.TabModelUtils;
import org.chromium.chrome.browser.tabmodel.TabPersistentStore;
import org.chromium.chrome.browser.tabmodel.TabbedModeTabPersistencePolicy;
import org.chromium.chrome.browser.tabpersistence.TabStateDirectory;
import org.chromium.chrome.browser.tabpersistence.TabStateFileManager;
import org.chromium.chrome.browser.tasks.ReturnToChromeUtil;
import org.chromium.chrome.browser.tasks.pseudotab.PseudoTab;
import org.chromium.chrome.browser.tasks.pseudotab.TabAttributeCache;
import org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper;
import org.chromium.chrome.browser.toolbar.top.ToolbarPhone;
import org.chromium.chrome.test.ChromeActivityTestRule;
import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
import org.chromium.chrome.test.R;
import org.chromium.chrome.test.util.ChromeApplicationTestUtils;
import org.chromium.chrome.test.util.browser.suggestions.SuggestionsDependenciesRule;
import org.chromium.chrome.test.util.browser.suggestions.mostvisited.FakeMostVisitedSites;
import org.chromium.content_public.browser.test.util.TestThreadUtils;
import org.chromium.content_public.browser.test.util.TestTouchUtils;
import org.chromium.url.GURL;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicReference;

/** Utility methods and classes for testing Start Surface. */
public class StartSurfaceTestUtils {
    public static final String INSTANT_START_TEST_BASE_PARAMS =
            "force-fieldtrial-params=Study.Group:"
                    + StartSurfaceConfiguration.START_SURFACE_RETURN_TIME_SECONDS_PARAM
                    + "/0";
    public static final String START_SURFACE_TEST_SINGLE_ENABLED_PARAMS =
            "force-fieldtrial-params=Study.Group:"
                    + "open_ntp_instead_of_start/false/open_start_as_homepage/true";
    public static final String START_SURFACE_TEST_BASE_PARAMS =
            "force-fieldtrial-params=Study.Group:";

    public static final String START_SURFACE_ON_TABLET_TEST_PARAMS =
            "force-fieldtrial-params=Study.Group:"
                    + StartSurfaceConfiguration.START_SURFACE_RETURN_TIME_ON_TABLET_SECONDS_PARAM
                    + "/0";
    public static List<ParameterSet> sClassParamsForStartSurfaceTest =
            Arrays.asList(
                    new ParameterSet().value(false, false).name("NoInstant_NoReturn"),
                    new ParameterSet().value(true, false).name("Instant_NoReturn"),
                    new ParameterSet().value(false, true).name("NoInstant_Return"),
                    new ParameterSet().value(true, true).name("Instant_Return"));

    /**
     * {@link ParameterProvider} used for parameterized tests with/without "Start Surface refactor"
     * flag enabled.
     */
    public static class RefactorTestParams implements ParameterProvider {
        private static List<ParameterSet> sRefactorTestParams =
                Arrays.asList(
                        new ParameterSet().value(false).name("RefactorDisabled"),
                        new ParameterSet().value(true).name("RefactorEnabled"));

        @Override
        public List<ParameterSet> getParameters() {
            return sRefactorTestParams;
        }
    }

    /** {@link ParameterProvider} used for tests with "Start Surface refactor" flag disabled. */
    public static class LegacyTestParams implements ParameterProvider {
        private static List<ParameterSet> sLegacyTestParams =
                Arrays.asList(new ParameterSet().value(false));

        @Override
        public List<ParameterSet> getParameters() {
            return sLegacyTestParams;
        }
    }

    private static final long MAX_TIMEOUT_MS = 30000L;

    /**
     * Set up StartSurfaceTest* based on whether it's immediateReturn or not.
     * @param immediateReturn Whether feature {@link ChromeFeatureList#START_SURFACE_RETURN_TIME} is
     *                        enabled as "immediately". When immediate return is enabled, the Start
     *                        surface is showing when Chrome is launched.
     * @param activityTestRule The test rule of activity under test.
     */
    public static void setUpStartSurfaceTests(
            boolean immediateReturn, ChromeTabbedActivityTestRule activityTestRule)
            throws IOException {
        BrowserControlsStateProvider fakeBrowserControlsStateProvider =
                new BrowserControlsStateProvider() {
                    @Override
                    public void addObserver(BrowserControlsStateProvider.Observer obs) {
                        assert false : "Not reached";
                    }

                    @Override
                    public void removeObserver(BrowserControlsStateProvider.Observer obs) {
                        assert false : "Not reached";
                    }

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

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

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

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

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

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

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

                    @Override
                    public boolean shouldAnimateBrowserControlsHeightChanges() {
                        return false;
                    }

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

                    @Override
                    public float getBrowserControlHiddenRatio() {
                        return 0.0f;
                    }

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

                    @Override
                    public float getTopVisibleContentOffset() {
                        return 0.0f;
                    }

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

        int expectedTabs = 1;
        int additionalTabs = expectedTabs - (immediateReturn ? 0 : 1);
        if (additionalTabs > 0) {
            int[] tabIDs = new int[additionalTabs];
            for (int i = 0; i < additionalTabs; i++) {
                tabIDs[i] = i;
                createThumbnailBitmapAndWriteToFile(i, fakeBrowserControlsStateProvider);
            }
            createTabStatesAndMetadataFile(tabIDs);
        }
        if (immediateReturn) {
            StartSurfaceConfiguration.START_SURFACE_RETURN_TIME_SECONDS.setForTesting(0);
            assertEquals(0, StartSurfaceConfiguration.START_SURFACE_RETURN_TIME_SECONDS.getValue());
            assertTrue(ReturnToChromeUtil.shouldShowTabSwitcher(-1, false));

            // Need to start main activity from launcher for immediate return to be effective.
            // However, need at least one tab for carousel to show, which starting main activity
            // from launcher doesn't provide.
            // Creating tabs and restart the activity would do the trick, but we cannot do that for
            // Instant start because we cannot unload native library.
            // Create fake TabState files to emulate having one tab in previous session.
            TabAttributeCache.setTitleForTesting(0, "tab title");
            startMainActivityFromLauncher(activityTestRule);
        } else {
            assertFalse(ReturnToChromeUtil.shouldShowTabSwitcher(-1, false));
            // Cannot use StartSurfaceTestUtils.startMainActivityFromLauncher().
            // Otherwise tab switcher could be shown immediately if single-pane is enabled.
            activityTestRule.startMainActivityOnBlankPage();
            onViewWaiting(withId(R.id.home_button));
        }
    }

    /**
     * Only launch Chrome without waiting for a current tab.
     * This method could not use {@link
     * ChromeTabbedActivityTestRule#startMainActivityFromLauncher()} because of its {@link
     * org.chromium.chrome.browser.tab.Tab} dependency.
     */
    public static void startMainActivityFromLauncher(ChromeActivityTestRule activityTestRule) {
        Intent intent = new Intent(Intent.ACTION_MAIN);
        intent.addCategory(Intent.CATEGORY_LAUNCHER);
        activityTestRule.prepareUrlIntent(intent, null);
        activityTestRule.launchActivity(intent);
    }

    public static void startAndWaitNativeInitialization(
            ChromeTabbedActivityTestRule activityTestRule) {
        CommandLine.getInstance().removeSwitch(ChromeSwitches.DISABLE_NATIVE_INITIALIZATION);
        TestThreadUtils.runOnUiThreadBlocking(
                () -> activityTestRule.getActivity().startDelayedNativeInitializationForTests());
        CriteriaHelper.pollUiThread(
                activityTestRule.getActivity().getTabModelSelector()::isTabStateInitialized,
                10000L,
                CriteriaHelper.DEFAULT_POLLING_INTERVAL);
        Assert.assertTrue(LibraryLoader.getInstance().isInitialized());
        ChromeTabbedActivity cta = activityTestRule.getActivity();
        StartSurfaceTestUtils.waitForStartSurfaceVisible(cta);
    }

    /**
     * Wait for the start surface homepage visible.
     * @param cta The ChromeTabbedActivity under test.
     */
    public static void waitForStartSurfaceVisible(ChromeTabbedActivity cta) {
        CriteriaHelper.pollUiThread(() -> cta.getLayoutManager() != null);
        LayoutTestUtils.waitForLayout(cta.getLayoutManager(), getStartSurfaceLayoutType());

        onViewWaiting(allOf(withId(R.id.primary_tasks_surface_view), isDisplayed()));
    }

    /**
     * Wait for the tab switcher page visible.
     * @param cta The ChromeTabbedActivity under test.
     */
    public static void waitForTabSwitcherVisible(ChromeTabbedActivity cta) {
        if (ChromeFeatureList.sStartSurfaceRefactor.isEnabled()) {
            LayoutTestUtils.waitForLayout(cta.getLayoutManager(), LayoutType.TAB_SWITCHER);
        } else {
            // TODO(1315676): Removes here when the Start surface refactoring is enabled by default.
            onViewWaiting(withId(R.id.secondary_tasks_surface_view));
        }
    }

    public static @LayoutType int getStartSurfaceLayoutType() {
        return ChromeFeatureList.sStartSurfaceRefactor.isEnabled()
                ? LayoutType.START_SURFACE
                : LayoutType.TAB_SWITCHER;
    }

    /**
     * Wait for the start surface homepage visible.
     * @param layoutChangedCallbackHelper The call back function to help check whether layout is
     *         changed.
     * @param currentlyActiveLayout The current active layout.
     * @param cta The ChromeTabbedActivity under test.
     */
    public static void waitForStartSurfaceVisible(
            CallbackHelper layoutChangedCallbackHelper,
            @LayoutType int currentlyActiveLayout,
            ChromeTabbedActivity cta) {
        waitForLayoutVisible(
                layoutChangedCallbackHelper,
                currentlyActiveLayout,
                cta,
                getStartSurfaceLayoutType());

        onViewWaiting(allOf(withId(R.id.primary_tasks_surface_view), isDisplayed()));
    }

    /**
     * Wait for the tab switcher page visible.
     * @param layoutChangedCallbackHelper The call back function to help check whether layout is
     *         changed.
     * @param currentlyActiveLayout The current active layout.
     * @param cta The ChromeTabbedActivity under test.
     */
    public static void waitForTabSwitcherVisible(
            CallbackHelper layoutChangedCallbackHelper,
            @LayoutType int currentlyActiveLayout,
            ChromeTabbedActivity cta) {
        waitForLayoutVisible(
                layoutChangedCallbackHelper, currentlyActiveLayout, cta, LayoutType.TAB_SWITCHER);
    }

    private static void waitForLayoutVisible(
            CallbackHelper layoutChangedCallbackHelper,
            @LayoutType int currentlyActiveLayout,
            ChromeTabbedActivity cta,
            @LayoutType int layoutType) {
        if (currentlyActiveLayout == layoutType) {
            StartSurfaceTestUtils.waitForTabModel(cta);
            return;
        }
        try {
            layoutChangedCallbackHelper.waitForNext(30L, TimeUnit.SECONDS);
            StartSurfaceTestUtils.waitForTabModel(cta);
        } catch (TimeoutException ex) {
            assert false : "Timeout waiting for browser to enter tab switcher / start surface.";
        }
    }

    /**
     * Wait for the tab state to be initialized.
     * @param cta The ChromeTabbedActivity under test.
     */
    public static void waitForTabModel(ChromeTabbedActivity cta) {
        CriteriaHelper.pollUiThread(
                cta.getTabModelSelector()::isTabStateInitialized,
                MAX_TIMEOUT_MS,
                CriteriaHelper.DEFAULT_POLLING_INTERVAL);
    }

    /**
     * Create all the files so that tab models can be restored.
     *
     * @param tabIds all the Tab IDs in the normal tab model.
     */
    public static void createTabStatesAndMetadataFile(int[] tabIds) throws IOException {
        createTabStatesAndMetadataFile(tabIds, null, 0);
    }

    /**
     * Create all the files so that tab models can be restored.
     *
     * @param tabIds all the Tab IDs in the normal tab model.
     * @param urls all of the URLs in the normal tab model.
     * @param selectedIndex the selected index of normal tab model.
     */
    public static void createTabStatesAndMetadataFile(
            int[] tabIds, @Nullable String[] urls, int selectedIndex) throws IOException {
        createTabStatesAndMetadataFile(tabIds, urls, selectedIndex, true);
    }

    private static void createTabStatesAndMetadataFile(
            int[] tabIds, @Nullable String[] urls, int selectedIndex, boolean createStateFile)
            throws IOException {
        TabPersistentStore.TabModelMetadata normalInfo =
                new TabPersistentStore.TabModelMetadata(selectedIndex);
        for (int i = 0; i < tabIds.length; i++) {
            normalInfo.ids.add(tabIds[i]);
            String url = urls != null ? urls[i] : "about:blank";
            normalInfo.urls.add(url);

            if (createStateFile) {
                saveTabState(tabIds[i], false);
            }
        }
        TabPersistentStore.TabModelMetadata incognitoInfo =
                new TabPersistentStore.TabModelMetadata(0);

        byte[] listData = TabPersistentStore.serializeMetadata(normalInfo, incognitoInfo);

        File metadataFile =
                new File(
                        TabStateDirectory.getOrCreateTabbedModeStateDirectory(),
                        TabbedModeTabPersistencePolicy.getMetadataFileNameForIndex(0));
        FileOutputStream output = new FileOutputStream(metadataFile);
        output.write(listData);
        output.close();
    }

    /**
     * Creates a Tab state metadata file without creating Tab state files for the given Tab's info.
     * @param tabIds All the Tab IDs in the normal tab model.
     * @param urls All the Tab URLs in the normal tab model.
     * @param selectedIndex The selected index of normal tab model.
     */
    public static void prepareTabStateMetadataFile(
            int[] tabIds, @Nullable String[] urls, int selectedIndex) throws IOException {
        createTabStatesAndMetadataFile(tabIds, urls, selectedIndex, false);
    }

    /**
     * Create thumbnail bitmap of the tab based on the given id and write it to file.
     * @param tabId The id of the target tab.
     * @param browserControlsStateProvider For getting the top offset.
     * @return The bitmap created.
     */
    public static Bitmap createThumbnailBitmapAndWriteToFile(
            int tabId, BrowserControlsStateProvider browserControlsStateProvider) {
        final int height = 100;
        final int width =
                (int)
                        Math.round(
                                height
                                        * TabUtils.getTabThumbnailAspectRatio(
                                                ContextUtils.getApplicationContext(),
                                                browserControlsStateProvider));
        final Bitmap thumbnailBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);

        try {
            File thumbnailFile = TabContentManager.getTabThumbnailFileJpeg(tabId);
            if (thumbnailFile.exists()) {
                thumbnailFile.delete();
            }
            Assert.assertFalse(thumbnailFile.exists());

            FileOutputStream thumbnailFileOutputStream = new FileOutputStream(thumbnailFile);
            thumbnailBitmap.compress(Bitmap.CompressFormat.JPEG, 100, thumbnailFileOutputStream);
            thumbnailFileOutputStream.flush();
            thumbnailFileOutputStream.close();

            Assert.assertTrue(thumbnailFile.exists());
        } catch (IOException e) {
            e.printStackTrace();
        }
        return thumbnailBitmap;
    }

    /**
     * Get the StartSurfaceCoordinator from UI thread.
     * @param cta The ChromeTabbedActivity under test.
     */
    public static StartSurfaceCoordinator getStartSurfaceFromUIThread(ChromeTabbedActivity cta) {
        AtomicReference<StartSurface> startSurface = new AtomicReference<>();
        TestThreadUtils.runOnUiThreadBlocking(() -> startSurface.set(cta.getStartSurface()));
        return (StartSurfaceCoordinator) startSurface.get();
    }

    /**
     * Gets the current active Tab from UI thread.
     * @param cta The ChromeTabbedActivity under test.
     */
    public static Tab getCurrentTabFromUIThread(ChromeTabbedActivity cta) {
        AtomicReference<Tab> tab = new AtomicReference<>();
        TestThreadUtils.runOnUiThreadBlocking(
                () -> tab.set(TabModelUtils.getCurrentTab(cta.getCurrentTabModel())));
        return tab.get();
    }

    /**
     * @param activityTestRule The test rule of activity under test.
     * @return Whether the keyboard is shown.
     */
    public static boolean isKeyboardShown(ChromeActivityTestRule activityTestRule) {
        Activity activity = activityTestRule.getActivity();
        if (activity.getCurrentFocus() == null) return false;
        return activityTestRule
                .getKeyboardDelegate()
                .isKeyboardShowing(activity, activity.getCurrentFocus());
    }

    /**
     * Scroll the start surface to make toolbar scrolled off.
     * @param cta The ChromeTabbedActivity under test.
     */
    public static void scrollToolbar(ChromeTabbedActivity cta) {
        // Toolbar layout should be hidden if start surface toolbar is shown on the top of the
        // screen.
        onView(withId(R.id.toolbar))
                .check(matches(withEffectiveVisibility(ViewMatchers.Visibility.GONE)));
        // The home button shouldn't show on homepage.
        onView(withId(R.id.home_button))
                .check(matches(withEffectiveVisibility(ViewMatchers.Visibility.GONE)));

        // Drag the Feed header title to scroll the toolbar to the top.
        int toY = -cta.getResources().getDimensionPixelOffset(R.dimen.toolbar_height_no_shadow);
        TestTouchUtils.dragCompleteView(
                InstrumentationRegistry.getInstrumentation(),
                cta.findViewById(R.id.header_title),
                0,
                0,
                0,
                toY,
                10);

        // The start surface toolbar should be scrolled up and not be displayed.
        CriteriaHelper.pollInstrumentationThread(
                () ->
                        cta.findViewById(R.id.tab_switcher_toolbar).getTranslationY()
                                <= (float)
                                        -cta.getResources()
                                                .getDimensionPixelOffset(
                                                        R.dimen.toolbar_height_no_shadow));

        // Toolbar layout view should show.
        onViewWaiting(withId(R.id.toolbar));

        // The start surface toolbar should be scrolled up and not be displayed.
        onView(withId(R.id.tab_switcher_toolbar)).check(matches(not(isDisplayed())));

        // Check the toolbar's background color.
        ToolbarPhone toolbar = cta.findViewById(R.id.toolbar);
        Assert.assertEquals(
                toolbar.getToolbarDataProvider().getPrimaryColor(),
                toolbar.getBackgroundDrawable().getColor());
    }

    /**
     * Navigate to homepage.
     * @param cta The ChromeTabbedActivity under test.
     */
    public static void pressHomePageButton(ChromeTabbedActivity cta) {
        TestThreadUtils.runOnUiThreadBlocking(
                () -> {
                    cta.getToolbarManager().getToolbarTabControllerForTesting().openHomepage();
                });
    }

    /**
     * Simulate pressing the back button.
     * @param activityTestRule The ChromeTabbedActivityTestRule under test.
     */
    public static void pressBack(ChromeTabbedActivityTestRule activityTestRule) {
        // ChromeTabbedActivity expects the native libraries to be loaded when back is pressed.
        activityTestRule.waitForActivityNativeInitializationComplete();
        TestThreadUtils.runOnUiThreadBlocking(
                () -> activityTestRule.getActivity().getOnBackPressedDispatcher().onBackPressed());
    }

    /**
     * Perform gesture navigate back action.
     * @param activityTestRule The ChromeTabbedActivityTestRule under test.
     */
    public static void gestureNavigateBack(ChromeTabbedActivityTestRule activityTestRule) {
        GestureNavigationUtils navUtils = new GestureNavigationUtils(activityTestRule);
        navUtils.swipeFromLeftEdge();
    }

    /**
     * Click the first MV tile (Explore tile) in mv_tiles_layout.
     * @param cta The ChromeTabbedActivity under test.
     * @param currentTabCount The correct number of normal tabs.
     */
    public static void launchFirstMVTile(ChromeTabbedActivity cta, int currentTabCount) {
        TabUiTestHelper.verifyTabModelTabCount(cta, currentTabCount, 0);
        onViewWaiting(withId(R.id.mv_tiles_layout))
                .perform(
                        new ViewAction() {
                            @Override
                            public Matcher<View> getConstraints() {
                                return isDisplayed();
                            }

                            @Override
                            public String getDescription() {
                                return "Click explore top sites view in MV tiles.";
                            }

                            @Override
                            public void perform(UiController uiController, View view) {
                                ViewGroup mvTilesContainer = (ViewGroup) view;
                                mvTilesContainer.getChildAt(0).performClick();
                            }
                        });
        LayoutTestUtils.waitForLayout(cta.getLayoutManager(), LayoutType.BROWSING);
        // Verifies a new Tab is created.
        TabUiTestHelper.verifyTabModelTabCount(cta, currentTabCount + 1, 0);
    }

    /**
     * Click the tab switcher button to navigate to tab switcher surface.
     * @param cta The ChromeTabbedActivity under test.
     */
    public static void clickTabSwitcherButton(ChromeTabbedActivity cta) {
        try {
            TestThreadUtils.runOnUiThreadBlocking(
                    () -> cta.findViewById(R.id.start_tab_switcher_button).performClick());
        } catch (ExecutionException e) {
            fail("Failed to tap 'more tabs' " + e.toString());
        }
    }

    /**
     * Set MV tiles on start surface by setting suggestionsDeps.
     * @param suggestionsDeps The SuggestionsDependenciesRule under test.
     * @return The MostVisitedSites the test used.
     */
    public static FakeMostVisitedSites setMVTiles(SuggestionsDependenciesRule suggestionsDeps) {
        FakeMostVisitedSites mostVisitedSites = new FakeMostVisitedSites();
        mostVisitedSites.setTileSuggestions(createFakeSiteSuggestions());
        suggestionsDeps.getFactory().mostVisitedSites = mostVisitedSites;
        return mostVisitedSites;
    }

    /** Returns a list of SiteSuggestion. */
    public static List<SiteSuggestion> createFakeSiteSuggestions() {
        List<SiteSuggestion> siteSuggestions = new ArrayList<>();
        String urlTemplate = new GURL("https://www.1.com/").serialize();
        for (int i = 0; i < 8; i++) {
            siteSuggestions.add(
                    new SiteSuggestion(
                            String.valueOf(i),
                            // Use pre-serialized GURL to avoid loading native.
                            GURL.deserialize(urlTemplate.replace("www.1.com", "www." + i + ".com")),
                            TileTitleSource.TITLE_TAG,
                            TileSource.TOP_SITES,
                            TileSectionType.PERSONALIZED));
        }

        return siteSuggestions;
    }

    /**
     * Wait for the deferred startup to be triggered.
     * @param activityTestRule The ChromeTabbedActivityTestRule under test.
     */
    public static void waitForDeferredStartup(ChromeTabbedActivityTestRule activityTestRule) {
        // Waits for the current Tab to complete loading. The deferred startup will be triggered
        // after the loading.
        waitForCurrentTabLoaded(activityTestRule);
        assertTrue("Deferred startup never completed", activityTestRule.waitForDeferredStartup());
    }

    /**
     * Waits for the current Tab to complete loading.
     * @param activityTestRule The ChromeTabbedActivityTestRule under test.
     */
    public static void waitForCurrentTabLoaded(ChromeTabbedActivityTestRule activityTestRule) {
        Tab tab = activityTestRule.getActivity().getActivityTab();
        if (tab != null && tab.isLoading()) {
            CriteriaHelper.pollUiThread(
                    () -> !tab.isLoading(),
                    MAX_TIMEOUT_MS,
                    CriteriaHelper.DEFAULT_POLLING_INTERVAL);
        }
    }

    /** Simulates pressing the Android's home button and bringing Chrome to the background. */
    public static void pressHome() {
        UiDevice device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
        device.pressHome();
        ChromeApplicationTestUtils.waitUntilChromeInBackground();
    }

    /** Presses the back button and verifies that Chrome goes to the background. */
    public static void pressBackAndVerifyChromeToBackground(ChromeTabbedActivityTestRule testRule) {
        // Verifies Chrome is closed.
        AsyncInitializationActivity.interceptMoveTaskToBackForTesting();
        pressBack(testRule);
        Assert.assertTrue(AsyncInitializationActivity.wasMoveTaskToBackInterceptedForTesting());
    }

    public static void waitForStatusBarColor(Activity activity, int expectedColor) {
        CriteriaHelper.pollUiThread(
                () -> {
                    Criteria.checkThat(
                            activity.getWindow().getStatusBarColor(), Matchers.is(expectedColor));
                },
                CriteriaHelper.DEFAULT_MAX_TIME_TO_POLL,
                CriteriaHelper.DEFAULT_POLLING_INTERVAL);
    }

    /**
     * Create a file so that a TabState can be restored later.
     * @param tabId the Tab ID
     * @param encrypted for Incognito mode
     */
    private static void saveTabState(int tabId, boolean encrypted) {
        File file =
                TabStateFileManager.getTabStateFile(
                        TabStateDirectory.getOrCreateTabbedModeStateDirectory(),
                        tabId,
                        encrypted,
                        /* isFlatBuffer= */ false);
        writeFile(file, M26_GOOGLE_COM.encodedTabState);

        TabState tabState = TabStateFileManager.restoreTabStateInternal(file, false);
        tabState.rootId = PseudoTab.fromTabId(tabId).getRootId();
        TabStateFileManager.saveStateInternal(file, tabState, encrypted);
    }

    private static void writeFile(File file, String data) {
        FileOutputStream outputStream = null;
        try {
            outputStream = new FileOutputStream(file);
            outputStream.write(Base64.decode(data, 0));
        } catch (Exception e) {
            assert false : "Failed to create " + file;
        } finally {
            StreamUtil.closeQuietly(outputStream);
        }
    }
}
