// Copyright 2016 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.chrome.browser;

import android.content.Context;
import android.support.test.InstrumentationRegistry;
import android.support.test.annotation.UiThreadTest;
import android.support.test.filters.SmallTest;
import android.support.test.rule.UiThreadTestRule;

import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.RuleChain;
import org.junit.runner.RunWith;

import org.chromium.base.task.PostTask;
import org.chromium.base.test.BaseJUnit4ClassRunner;
import org.chromium.base.test.util.MetricsUtils;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.init.ChromeBrowserInitializer;
import org.chromium.chrome.browser.profiles.Profile;
import org.chromium.chrome.browser.test.ChromeBrowserTestRule;
import org.chromium.content_public.browser.UiThreadTaskTraits;
import org.chromium.content_public.browser.WebContents;
import org.chromium.content_public.browser.WebContentsObserver;
import org.chromium.content_public.browser.test.util.Criteria;
import org.chromium.content_public.browser.test.util.CriteriaHelper;
import org.chromium.content_public.browser.test.util.TestThreadUtils;
import org.chromium.content_public.browser.test.util.WebContentsUtils;
import org.chromium.net.test.EmbeddedTestServer;

import java.util.concurrent.Callable;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;

/** Tests for {@link WarmupManager} */
@RunWith(BaseJUnit4ClassRunner.class)
public class WarmupManagerTest {
    @Rule
    public final RuleChain mChain =
            RuleChain.outerRule(new ChromeBrowserTestRule()).around(new UiThreadTestRule());

    private WarmupManager mWarmupManager;
    private Context mContext;

    @Before
    public void setUp() throws Exception {
        mContext = InstrumentationRegistry.getInstrumentation()
                           .getTargetContext()
                           .getApplicationContext();
        TestThreadUtils.runOnUiThreadBlocking(new Callable<Void>() {
            @Override
            public Void call() throws Exception {
                ChromeBrowserInitializer.getInstance(mContext).handleSynchronousStartup();
                mWarmupManager = WarmupManager.getInstance();
                return null;
            }
        });
    }

    @After
    public void tearDown() throws Exception {
        TestThreadUtils.runOnUiThreadBlocking(() -> mWarmupManager.destroySpareWebContents());
    }

    @Test
    @SmallTest
    public void testCreateAndTakeSpareRenderer() {
        final AtomicBoolean isRenderViewReady = new AtomicBoolean();
        final AtomicReference<WebContents> webContentsReference = new AtomicReference<>();

        PostTask.runOrPostTask(UiThreadTaskTraits.DEFAULT, () -> {
            mWarmupManager.createSpareWebContents(!WarmupManager.FOR_CCT);
            Assert.assertTrue(mWarmupManager.hasSpareWebContents());
            WebContents webContents =
                    mWarmupManager.takeSpareWebContents(false, false, !WarmupManager.FOR_CCT);
            Assert.assertNotNull(webContents);
            Assert.assertFalse(mWarmupManager.hasSpareWebContents());
            WebContentsObserver observer = new WebContentsObserver(webContents) {
                @Override
                public void renderViewReady() {
                    isRenderViewReady.set(true);
                }
            };

            // This is not racy because {@link WebContentsObserver} methods are called on the UI
            // thread by posting a task. See {@link RenderViewHostImpl::PostRenderViewReady}.
            webContents.addObserver(observer);
            webContentsReference.set(webContents);
        });
        CriteriaHelper.pollUiThread(new Criteria("Spare renderer is not initialized") {
            @Override
            public boolean isSatisfied() {
                return isRenderViewReady.get();
            }
        });
        PostTask.runOrPostTask(
                UiThreadTaskTraits.DEFAULT, () -> webContentsReference.get().destroy());
    }

    /** Tests that taking a spare WebContents makes it unavailable to subsequent callers. */
    @Test
    @SmallTest
    @UiThreadTest
    public void testTakeSpareWebContents() throws Throwable {
        mWarmupManager.createSpareWebContents(!WarmupManager.FOR_CCT);
        WebContents webContents =
                mWarmupManager.takeSpareWebContents(false, false, !WarmupManager.FOR_CCT);
        Assert.assertNotNull(webContents);
        Assert.assertFalse(mWarmupManager.hasSpareWebContents());
        webContents.destroy();
    }

    @Test
    @SmallTest
    @UiThreadTest
    public void testTakeSpareWebContentsChecksArguments() throws Throwable {
        mWarmupManager.createSpareWebContents(!WarmupManager.FOR_CCT);
        Assert.assertNull(mWarmupManager.takeSpareWebContents(true, false, !WarmupManager.FOR_CCT));
        Assert.assertNull(mWarmupManager.takeSpareWebContents(true, true, !WarmupManager.FOR_CCT));
        Assert.assertTrue(mWarmupManager.hasSpareWebContents());
        Assert.assertNotNull(
                mWarmupManager.takeSpareWebContents(false, true, !WarmupManager.FOR_CCT));
        Assert.assertFalse(mWarmupManager.hasSpareWebContents());
    }

    @Test
    @SmallTest
    @UiThreadTest
    public void testClearsDeadWebContents() throws Throwable {
        mWarmupManager.createSpareWebContents(!WarmupManager.FOR_CCT);
        WebContentsUtils.simulateRendererKilled(mWarmupManager.mSpareWebContents, false);
        Assert.assertNull(
                mWarmupManager.takeSpareWebContents(false, false, !WarmupManager.FOR_CCT));
    }

    @Test
    @SmallTest
    @UiThreadTest
    public void testRecordWebContentsStatus() throws Throwable {
        String name = WarmupManager.WEBCONTENTS_STATUS_HISTOGRAM;
        MetricsUtils.HistogramDelta createdDelta =
                new MetricsUtils.HistogramDelta(name, WarmupManager.WebContentsStatus.CREATED);
        MetricsUtils.HistogramDelta usedDelta =
                new MetricsUtils.HistogramDelta(name, WarmupManager.WebContentsStatus.USED);
        MetricsUtils.HistogramDelta killedDelta =
                new MetricsUtils.HistogramDelta(name, WarmupManager.WebContentsStatus.KILLED);
        MetricsUtils.HistogramDelta destroyedDelta =
                new MetricsUtils.HistogramDelta(name, WarmupManager.WebContentsStatus.DESTROYED);
        MetricsUtils.HistogramDelta stolenDelta =
                new MetricsUtils.HistogramDelta(name, WarmupManager.WebContentsStatus.STOLEN);

        // Created, used.
        mWarmupManager.createSpareWebContents(WarmupManager.FOR_CCT);
        Assert.assertEquals(1, createdDelta.getDelta());
        Assert.assertNotNull(
                mWarmupManager.takeSpareWebContents(false, false, WarmupManager.FOR_CCT));
        Assert.assertEquals(1, usedDelta.getDelta());

        // Created, killed.
        mWarmupManager.createSpareWebContents(WarmupManager.FOR_CCT);
        Assert.assertEquals(2, createdDelta.getDelta());
        Assert.assertNotNull(mWarmupManager.mSpareWebContents);
        WebContentsUtils.simulateRendererKilled(mWarmupManager.mSpareWebContents, false);
        Assert.assertEquals(1, killedDelta.getDelta());
        Assert.assertNull(mWarmupManager.takeSpareWebContents(false, false, WarmupManager.FOR_CCT));

        // Created, destroyed.
        mWarmupManager.createSpareWebContents(WarmupManager.FOR_CCT);
        Assert.assertEquals(3, createdDelta.getDelta());
        Assert.assertNotNull(mWarmupManager.mSpareWebContents);
        mWarmupManager.destroySpareWebContents();
        Assert.assertEquals(1, destroyedDelta.getDelta());

        // Created, stolen.
        mWarmupManager.createSpareWebContents(WarmupManager.FOR_CCT);
        Assert.assertEquals(4, createdDelta.getDelta());
        Assert.assertNotNull(
                mWarmupManager.takeSpareWebContents(false, false, !WarmupManager.FOR_CCT));
        Assert.assertEquals(1, stolenDelta.getDelta());

        // Created, used, not for CCT.
        mWarmupManager.createSpareWebContents(!WarmupManager.FOR_CCT);
        Assert.assertEquals(4, createdDelta.getDelta());
        Assert.assertNotNull(
                mWarmupManager.takeSpareWebContents(false, false, !WarmupManager.FOR_CCT));
        Assert.assertEquals(1, stolenDelta.getDelta());
        Assert.assertEquals(1, usedDelta.getDelta());
    }

    /** Checks that the View inflation works. */
    @Test
    @SmallTest
    @UiThreadTest
    public void testInflateLayout() throws Throwable {
        int layoutId = R.layout.custom_tabs_control_container;
        int toolbarId = R.layout.custom_tabs_toolbar;
        mWarmupManager.initializeViewHierarchy(mContext, layoutId, toolbarId);
        Assert.assertTrue(mWarmupManager.hasViewHierarchyWithToolbar(layoutId));
    }

    /** Tests that preconnects can be initiated from the Java side. */
    @Test
    @SmallTest
    public void testPreconnect() throws Exception {
        EmbeddedTestServer server = new EmbeddedTestServer();
        try {
            // The predictor prepares 2 connections when asked to preconnect. Initializes the
            // semaphore to be unlocked after 2 connections.
            final Semaphore connectionsSemaphore = new Semaphore(1 - 2);

            // Cannot use EmbeddedTestServer#createAndStartServer(), as we need to add the
            // connection listener.
            server.initializeNative(mContext, EmbeddedTestServer.ServerHTTPSSetting.USE_HTTP);
            server.addDefaultHandlers("");
            server.setConnectionListener(new EmbeddedTestServer.ConnectionListener() {
                @Override
                public void acceptedSocket(long socketId) {
                    connectionsSemaphore.release();
                }
            });
            server.start();

            final String url = server.getURL("/hello_world.html");
            PostTask.runOrPostTask(UiThreadTaskTraits.DEFAULT,
                    () -> mWarmupManager.maybePreconnectUrlAndSubResources(
                                    Profile.getLastUsedProfile(), url));
            if (!connectionsSemaphore.tryAcquire(5, TimeUnit.SECONDS)) {
                // Starts at -1.
                int actualConnections = connectionsSemaphore.availablePermits() + 1;
                Assert.fail("Expected 2 connections, got " + actualConnections);
            }
        } finally {
            server.stopAndDestroyServer();
        }
    }
}
