// 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 android.os.Handler;
import android.os.Looper;

import java.util.concurrent.atomic.AtomicBoolean;

/**
 * This class is usefull when writing instrumentation tests that exercise code that posts tasks
 * (to the same thread).
 * Since the test code is run in a single thread, the posted tasks are never executed.
 * The TestThread class lets you run that code on a specific thread synchronously and flush the
 * message loop on that thread.
 *
 * Example of test using this:
 *
 * public void testMyAwesomeClass() {
 *   TestThread testThread = new TestThread();
 *   testThread.startAndWaitForReadyState();
 *
 *   testThread.runOnTestThreadSyncAndProcessPendingTasks(new Runnable() {
 *       @Override
 *       public void run() {
 *           MyAwesomeClass.doStuffAsync();
 *       }
 *   });
 *   // Once we get there we know doStuffAsync has been executed and all the tasks it posted.
 *   assertTrue(MyAwesomeClass.stuffWasDone());
 * }
 *
 * Notes:
 * - this is only for tasks posted to the same thread. Anyway if you were posting to a different
 *   thread, you'd probably need to set that other thread up.
 * - this only supports tasks posted using Handler.post(), it won't work with postDelayed and
 *   postAtTime.
 * - if your test instanciates an object and that object is the one doing the posting of tasks, you
 *   probably want to instanciate it on the test thread as it might create the Handler it posts
 *   tasks to in the constructor.
 */

public class TestThread extends Thread {
    private final Object mThreadReadyLock;
    private AtomicBoolean mThreadReady;
    private Handler mMainThreadHandler;
    private Handler mTestThreadHandler;

    public TestThread() {
        mMainThreadHandler = new Handler();
        // We can't use the AtomicBoolean as the lock or findbugs will freak out...
        mThreadReadyLock = new Object();
        mThreadReady = new AtomicBoolean();
    }

    @Override
    public void run() {
        Looper.prepare();
        mTestThreadHandler = new Handler();
        mTestThreadHandler.post(new Runnable() {
            @Override
            public void run() {
                synchronized (mThreadReadyLock) {
                    mThreadReady.set(true);
                    mThreadReadyLock.notify();
                }
            }
        });
        Looper.loop();
    }

    /**
     * Starts this TestThread and blocks until it's ready to accept calls.
     */
    public void startAndWaitForReadyState() {
        checkOnMainThread();
        start();
        synchronized (mThreadReadyLock) {
            try {
                // Note the mThreadReady and while are not really needed.
                // There are there so findbugs don't report warnings.
                while (!mThreadReady.get()) {
                    mThreadReadyLock.wait();
                }
            } catch (InterruptedException ie) {
                System.err.println("Error starting TestThread.");
                ie.printStackTrace();
            }
        }
    }

    /**
     * Runs the passed Runnable synchronously on the TestThread and returns when all pending
     * runnables have been excuted.
     * Should be called from the main thread.
     */
    public void runOnTestThreadSyncAndProcessPendingTasks(Runnable r) {
        checkOnMainThread();

        runOnTestThreadSync(r);

        // Run another task, when it's done it means all pendings tasks have executed.
        runOnTestThreadSync(null);
    }

    /**
     * Runs the passed Runnable on the test thread and blocks until it has finished executing.
     * Should be called from the main thread.
     * @param r The runnable to be executed.
     */
    public void runOnTestThreadSync(final Runnable r) {
        checkOnMainThread();
        final Object lock = new Object();
        // Task executed is not really needed since we are only on one thread, it is here to appease
        // findbugs.
        final AtomicBoolean taskExecuted = new AtomicBoolean();
        mTestThreadHandler.post(new Runnable() {
            @Override
            public void run() {
                if (r != null) r.run();
                synchronized (lock) {
                    taskExecuted.set(true);
                    lock.notify();
                }
            }
        });
        synchronized (lock) {
            try {
                while (!taskExecuted.get()) {
                    lock.wait();
                }
            } catch (InterruptedException ie) {
                ie.printStackTrace();
            }
        }
    }

    private void checkOnMainThread() {
        assert Looper.myLooper() == mMainThreadHandler.getLooper();
    }
}
