/*
 * Copyright (C) 2014 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 com.android.compatibility.common.util;

import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

import android.util.Log;

import junit.framework.Assert;

/**
 * Used to fail a test if a function takes more than a certain amount of time.
 */
public class WatchDog implements Runnable {
    private static final String TAG = WatchDog.class.getSimpleName();
    private Thread mThread;
    private Semaphore mSemaphore;
    private volatile boolean mStopRequested;
    private final long mTimeoutInMilliSecs;
    private TimeoutCallback mCallback = null;

    public WatchDog(long timeoutInMilliSecs) {
        mTimeoutInMilliSecs = timeoutInMilliSecs;
    }

    public WatchDog(long timeoutInMilliSecs, TimeoutCallback callback) {
        this(timeoutInMilliSecs);
        mCallback = callback;
    }

    /** start watch-dog */
    public void start() {
        Log.i(TAG, "start");
        mStopRequested = false;
        mSemaphore = new Semaphore(0);
        mThread = new Thread(this);
        mThread.start();
    }

    /** stop watch-dog */
    public void stop() {
        Log.i(TAG, "stop");
        if (mThread == null) {
            return; // already finished
        }
        mStopRequested = true;
        mSemaphore.release();
        try {
            mThread.join();
        } catch (InterruptedException e) {
            // ignore
        }
        mThread = null;
        mSemaphore = null;
    }

    /** resets watch-dog, thus prevent it from panic */
    public void reset() {
        if (!mStopRequested) { // stop requested, but rendering still on-going
            mSemaphore.release();
        }
    }

    @Override
    public void run() {
        while (!mStopRequested) {
            try {
                boolean success = mSemaphore.tryAcquire(mTimeoutInMilliSecs, TimeUnit.MILLISECONDS);
                if (mCallback == null) {
                    Assert.assertTrue("Watchdog timed-out", success);
                } else if (!success) {
                    mCallback.onTimeout();
                }
            } catch (InterruptedException e) {
                // this thread will not be interrupted,
                // but if it happens, just check the exit condition.
            }
        }
    }

    /**
     * Called by the Watchdog when it has timed out.
     */
    public interface TimeoutCallback {

        public void onTimeout();
    }
}
