// Copyright 2012 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.base.test.util;

import static org.chromium.base.test.util.ScalableTimeout.scaleTimeout;

import org.junit.Assert;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

/**
 * A helper class that encapsulates listening and blocking for callbacks.
 *
 * Sample usage:
 *
 * // Let us assume that this interface is defined by some piece of production code and is used
 * // to communicate events that occur in that piece of code. Let us further assume that the
 * // production code runs on the main thread test code runs on a separate test thread.
 * // An instance that implements this interface would be injected by test code to ensure that the
 * // methods are being called on another thread.
 * interface Delegate {
 *     void onOperationFailed(String errorMessage);
 *     void onDataPersisted();
 * }
 *
 * // This is the inner class you'd write in your test case to later inject into the production
 * // code.
 * class TestDelegate implements Delegate {
 *     // This is the preferred way to create a helper that stores the parameters it receives
 *     // when called by production code.
 *     public static class OnOperationFailedHelper extends CallbackHelper {
 *         private String mErrorMessage;
 *
 *         public void getErrorMessage() {
 *             assert getCallCount() > 0;
 *             return mErrorMessage;
 *         }
 *
 *         public void notifyCalled(String errorMessage) {
 *             mErrorMessage = errorMessage;
 *             // It's important to call this after all parameter assignments.
 *             notifyCalled();
 *         }
 *     }
 *
 *     // There should be one CallbackHelper instance per method.
 *     private OnOperationFailedHelper mOnOperationFailedHelper;
 *     private CallbackHelper mOnDataPersistedHelper;
 *
 *     public OnOperationFailedHelper getOnOperationFailedHelper() {
 *         return mOnOperationFailedHelper;
 *     }
 *
 *     public CallbackHelper getOnDataPersistedHelper() {
 *         return mOnDataPersistedHelper;
 *     }
 *
 *     @Override
 *     public void onOperationFailed(String errorMessage) {
 *         mOnOperationFailedHelper.notifyCalled(errorMessage);
 *     }
 *
 *     @Override
 *     public void onDataPersisted() {
 *         mOnDataPersistedHelper.notifyCalled();
 *     }
 * }
 *
 * // This is a sample test case.
 * public void testCase() throws Exception {
 *     // Create the TestDelegate to inject into production code.
 *     TestDelegate delegate = new TestDelegate();
 *     // Create the production class instance that is being tested and inject the test delegate.
 *     CodeUnderTest codeUnderTest = new CodeUnderTest();
 *     codeUnderTest.setDelegate(delegate);
 *
 *     // Typically you'd get the current call count before performing the operation you expect to
 *     // trigger the callback. There can't be any callbacks 'in flight' at this moment, otherwise
 *     // the call count is unpredictable and the test will be flaky.
 *     int onOperationFailedCallCount = delegate.getOnOperationFailedHelper().getCallCount();
 *     codeUnderTest.doSomethingThatEndsUpCallingOnOperationFailedFromAnotherThread();
 *     // It's safe to do other stuff here, if needed.
 *     ....
 *     // Wait for the callback if it hadn't been called yet, otherwise return immediately. This
 *     // can throw an exception if the callback doesn't arrive within the timeout.
 *     delegate.getOnOperationFailedHelper().waitForCallback(onOperationFailedCallCount);
 *     // Access to method parameters is now safe.
 *     assertEquals("server error", delegate.getOnOperationFailedHelper().getErrorMessage());
 *
 *     // Being able to pass the helper around lets us build methods which encapsulate commonly
 *     // performed tasks.
 *     doSomeOperationAndWait(codeUnerTest, delegate.getOnOperationFailedHelper());
 *
 *     // The helper can be reused for as many calls as needed, just be sure to get the count each
 *     // time.
 *     onOperationFailedCallCount = delegate.getOnOperationFailedHelper().getCallCount();
 *     codeUnderTest.doSomethingElseButStillFailOnAnotherThread();
 *     delegate.getOnOperationFailedHelper().waitForCallback(onOperationFailedCallCount);
 *
 *     // It is also possible to use more than one helper at a time.
 *     onOperationFailedCallCount = delegate.getOnOperationFailedHelper().getCallCount();
 *     int onDataPersistedCallCount = delegate.getOnDataPersistedHelper().getCallCount();
 *     codeUnderTest.doSomethingThatPersistsDataButFailsInSomeOtherWayOnAnotherThread();
 *     delegate.getOnDataPersistedHelper().waitForCallback(onDataPersistedCallCount);
 *     delegate.getOnOperationFailedHelper().waitForCallback(onOperationFailedCallCount);
 * }
 *
 * // Shows how to turn an async operation + completion callback into a synchronous operation.
 * private void doSomeOperationAndWait(final CodeUnderTest underTest,
 *         CallbackHelper operationHelper) throws InterruptedException, TimeoutException {
 *     final int callCount = operationHelper.getCallCount();
 *     getInstrumentation().runOnMainSync(new Runnable() {
 *         @Override
 *         public void run() {
 *             // This schedules a call to a method on the injected TestDelegate. The TestDelegate
 *             // implementation will then call operationHelper.notifyCalled().
 *             underTest.operation();
 *         }
 *      });
 *      operationHelper.waitForCallback(callCount);
 * }
 *
 */
public class CallbackHelper {
    /** The default timeout (in seconds) for a callback to wait. */
    public static final long WAIT_TIMEOUT_SECONDS = scaleTimeout(5);

    private final Object mLock = new Object();
    private int mCallCount;
    private String mFailureString;

    /**
     * Gets the number of times the callback has been called.
     *
     * The call count can be used with the waitForCallback() method, indicating a point
     * in time after which the caller wishes to record calls to the callback.
     *
     * In order to wait for a callback caused by X, the call count should be obtained
     * before X occurs.
     *
     * NOTE: any call to the callback that occurs after the call count is obtained
     * will result in the corresponding wait call to resume execution. The call count
     * is intended to 'catch' callbacks that occur after X but before waitForCallback()
     * is called.
     */
    public int getCallCount() {
        synchronized (mLock) {
            return mCallCount;
        }
    }

    /**
     * Blocks until the callback is called the specified number of
     * times or throws an exception if we exceeded the specified time frame.
     *
     * This will wait for a callback to be called a specified number of times after
     * the point in time at which the call count was obtained.  The method will return
     * immediately if a call occurred the specified number of times after the
     * call count was obtained but before the method was called, otherwise the method will
     * block until the specified call count is reached.
     *
     * @param msg The error message to use if the callback times out.
     * @param currentCallCount the value obtained by calling getCallCount().
     * @param numberOfCallsToWaitFor number of calls (counting since
     *                               currentCallCount was obtained) that we will wait for.
     * @param timeout timeout value. We will wait the specified amount of time for a single
     *                callback to occur so the method call may block up to
     *                <code>numberOfCallsToWaitFor * timeout</code> units.
     * @param unit timeout unit.
     * @throws InterruptedException
     * @throws TimeoutException Thrown if the method times out before onPageFinished is called.
     */
    public void waitForCallback(String msg, int currentCallCount, int numberOfCallsToWaitFor,
            long timeout, TimeUnit unit) throws InterruptedException, TimeoutException {
        assert mCallCount >= currentCallCount;
        assert numberOfCallsToWaitFor > 0;
        synchronized (mLock) {
            int callCountWhenDoneWaiting = currentCallCount + numberOfCallsToWaitFor;
            while (callCountWhenDoneWaiting > mCallCount) {
                int callCountBeforeWait = mCallCount;
                mLock.wait(unit.toMillis(timeout));
                if (mFailureString != null) {
                    String s = mFailureString;
                    mFailureString = null;
                    Assert.fail(s);
                }
                if (callCountBeforeWait == mCallCount) {
                    throw new TimeoutException(msg == null ? "waitForCallback timed out!" : msg);
                }
            }
        }
    }

    /**
     * @see #waitForCallback(String, int, int, long, TimeUnit)
     */
    public void waitForCallback(int currentCallCount, int numberOfCallsToWaitFor, long timeout,
            TimeUnit unit) throws InterruptedException, TimeoutException {
        waitForCallback(null, currentCallCount, numberOfCallsToWaitFor, timeout, unit);
    }

    /**
     * @see #waitForCallback(String, int, int, long, TimeUnit)
     */
    public void waitForCallback(int currentCallCount, int numberOfCallsToWaitFor)
            throws InterruptedException, TimeoutException {
        waitForCallback(null, currentCallCount, numberOfCallsToWaitFor,
                WAIT_TIMEOUT_SECONDS, TimeUnit.SECONDS);
    }

    /**
     * @see #waitForCallback(String, int, int, long, TimeUnit)
     */
    public void waitForCallback(String msg, int currentCallCount)
            throws InterruptedException, TimeoutException {
        waitForCallback(msg, currentCallCount, 1, WAIT_TIMEOUT_SECONDS, TimeUnit.SECONDS);
    }

    /**
     * @see #waitForCallback(String, int, int, long, TimeUnit)
     */
    public void waitForCallback(int currentCallCount)
            throws InterruptedException, TimeoutException {
        waitForCallback(null, currentCallCount, 1, WAIT_TIMEOUT_SECONDS, TimeUnit.SECONDS);
    }

    /**
     * @see #waitForCallback(String, int, int, long, TimeUnit)
     */
    public void waitForCallback(String msg) throws InterruptedException, TimeoutException {
        waitForCallback(msg, getCallCount());
    }

    /**
     * @see #waitForCallback(String, int, int, long, TimeUnit)
     */
    public void waitForCallback() throws InterruptedException, TimeoutException {
        waitForCallback(getCallCount());
    }

    /**
     * Should be called when the callback associated with this helper object is called.
     */
    public void notifyCalled() {
        synchronized (mLock) {
            mCallCount++;
            mLock.notifyAll();
        }
    }

    /**
     * Should be called when the callback associated with this helper object wants to
     * indicate a failure.
     *
     * @param s The failure message.
     */
    public void notifyFailed(String s) {
        synchronized (mLock) {
            mFailureString = s;
            mLock.notifyAll();
        }
    }
}
