/*
 * Copyright 2015-present Open Networking Foundation
 *
 * 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 org.onlab.util;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;

/**
 * Mutable boolean that allows threads to wait for a specified value.
 */
public class BlockingBoolean extends AbstractQueuedSynchronizer {

    private static final int TRUE = 1;
    private static final int FALSE = 0;

    /**
     * Creates a new blocking boolean with the specified value.
     *
     * @param value the starting value
     */
    public BlockingBoolean(boolean value) {
        setState(value ? TRUE : FALSE);
    }

    /**
     * Causes the current thread to wait until the boolean equals the specified
     * value unless the thread is {@linkplain Thread#interrupt interrupted}.
     *
     * @param value specified value
     * @throws InterruptedException if interrupted while waiting
     */
    public void await(boolean value) throws InterruptedException {
        acquireSharedInterruptibly(value ? TRUE : FALSE);
    }

    /**
     * Causes the current thread to wait until the boolean equals the specified
     * value unless the thread is {@linkplain Thread#interrupt interrupted},
     * or the specified waiting time elapses.
     *
     * @param value specified value
     * @param timeout the maximum time to wait
     * @param unit the time unit of the {@code timeout} argument
     * @return {@code true} if the count reached zero and {@code false}
     *         if the waiting time elapsed before the count reached zero
     * @throws InterruptedException if interrupted while waiting
     */
    public boolean await(boolean value, long timeout, TimeUnit unit)
            throws InterruptedException {
        return tryAcquireSharedNanos(value ? TRUE : FALSE, unit.toNanos(timeout));
    }

    protected int tryAcquireShared(int acquires) {
        return (getState() == acquires) ? 1 : -1;
    }

    /**
     * Sets the value of the blocking boolean.
     *
     * @param value new value
     */
    public void set(boolean value) {
        releaseShared(value ? TRUE : FALSE);
    }

    /**
     * Gets the value of the blocking boolean.
     *
     * @return current value
     */
    public boolean get() {
        return getState() == TRUE;
    }

    protected boolean tryReleaseShared(int releases) {
        // Signal on state change only
        int state = getState();
        if (state == releases) {
            return false;
        }
        return compareAndSetState(state, releases);
    }

}
