/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.apache.ode.bpel.engine;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * An N state synchronization latch useful for implementing hydration/dehydration. The
 * latch functions as follows. At any time, the latch is in one of N states and has a
 * count. Clients can "latch" and "release" the latch, which increments/decrements the
 * count; however, when latching, a state must be specified. If the state does not match
 * the current state, the latch blocks until the count is zero. Essentially, the latch
 * can change state only when the count is zero. Every time the latch changes state an
 * optional {@link Runnable} corresponding to the new state is executed.
 *
 * @author Maciej Szefler ( m s z e f l e r @ g m a i l . c o m )
 */
public class NStateLatch {
    static final Logger __log = LoggerFactory.getLogger(NStateLatch.class);

    /** Current state. */
    private int _state = -1;

    /** Current depth (i.e. number of enter() calls) */
    private int _depth = 0;

    /** Action for state transition ?-->i */
    protected Runnable _transitions[];

    /** Synchronization lock .*/
    private Lock _lock;

    /** _depth == 0 condition. */
    private Condition _depth0;

    private boolean _transitioning = false;

    /**
     * Constructor, the array of {@link Runnable}s defines the number of states and the transition
     * actions.
     * @param transitions action to perform when entering state x.
     */
    public NStateLatch(Runnable [] transitions) {
        _transitions = transitions;
        _lock = new ReentrantLock();
        _depth0 = _lock.newCondition();
    }

    public void latch(int state) {
        if (state >= _transitions.length || state < 0)
            throw new IllegalArgumentException("Invalid state.");

        _lock.lock();
        try {
            if (_transitioning )
                throw new IllegalStateException("Manipulating latch from transition. ");

            if (_state != state) {
                // wait for the depth to become 0
                while (_depth != 0)
                    _depth0.awaitUninterruptibly();

                if (_state != state) {
                    if (_transitions[state] != null)
                        try {
                            _transitioning = true;
                            _transitions[state].run();
                        } finally {
                            _transitioning = false;
                        }
                    _state = state;
                }
            }
        } finally {
            _depth ++;
            _lock.unlock();
        }
    }

    public void release(int state) {
        _lock.lock();
        try {

            if (_transitioning )
                throw new IllegalStateException("Manipulating latch from transition. ");

            if (_state != state)
                __log.error("Latch error, was releasing for state " + state + " but actually in " + _state);
            if (_depth <= 0)
                throw new IllegalStateException("Too many release() calls.");

            _depth --;

            if (_depth == 0)
                _depth0.signal();
        } finally {
            _lock.unlock();
        }
    }

    public int getDepth(int state) {
        return (_state == state ? _depth : 0);
    }
}
