/*
 * 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.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ode.bpel.clapi.ClusterLock;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;

/**
 *
 * WARNING --- EXPERIMENTAL
 *
 * Mechanism for obtaining instance-level locks. Very simple implementation at the moment, that is only valid
 * for a single processing node. To move to multi-processor setup we'll need to implement this lock in the database.
 *
 * @author Maciej Szefler - m s z e f l e r @ g m a i l . c o m
 */
public class InstanceLockManager implements ClusterLock<Long> {
    private static final Log __log = LogFactory.getLog(InstanceLockManager.class);

    private final Lock _mutex = new java.util.concurrent.locks.ReentrantLock();
    private final Map<Long, InstanceInfo> _locks = new HashMap<Long,InstanceInfo>();

    public void lock(Long key) {
        // Noting to do here.
    }

    public void lock(Long iid, int time, TimeUnit tu) throws InterruptedException, TimeoutException {
        if (iid == null) return;

        String thrd = Thread.currentThread().toString();
        if (__log.isDebugEnabled())
            __log.debug(thrd + ": lock(iid=" + iid + ", time=" + time + tu+")");

        InstanceInfo li;

        _mutex.lock();
        try {

            while (true) {
                li = _locks.get(iid);
                if (li == null) {
                    li = new InstanceInfo(iid, Thread.currentThread());
                    _locks.put(iid, li);
                    if (__log.isDebugEnabled())
                        __log.debug(thrd + ": lock(iid=" + iid + ", time=" + time + tu+")-->GRANTED");
                    return;
                } else {
                    if (__log.isDebugEnabled())
                        __log.debug(thrd + ": lock(iid=" + iid + ", time=" + time + tu+")-->WAITING(held by " + li.acquierer + ")");

                    if (!li.available.await(time, tu)) {
                        if (__log.isDebugEnabled())
                            __log.debug(thrd + ": lock(iid=" + iid + ", time=" + time + tu+")-->TIMEOUT (held by " + li.acquierer + ")");
                        throw new TimeoutException();
                    }
                }
            }

        } finally {
            _mutex.unlock();
        }

    }

    public void unlock(Long iid)  {
        if (iid == null) return;

        String thrd = Thread.currentThread().toString();
        if (__log.isDebugEnabled())
            __log.debug(thrd + ": unlock(iid=" + iid + ")");

        _mutex.lock();
        try {
            InstanceInfo li = _locks.get(iid);
            if (li == null)
                throw new IllegalStateException("Instance not locked, cannot unlock!");

            _locks.remove(iid);

            // Note, that we have to signall all threads, because new holder will create a new
            // instance of "available" condition variable, so all the waiters need to try again
            li.available.signalAll();

        } finally {
            _mutex.unlock();
        }

    }

    public boolean tryLock(Long key) {
        // Noting to do here.
        return false;
    }

    public boolean tryLock(Long key, int time, TimeUnit tu) {
        // Noting to do here.
        return false;
    }

    public void putIfAbsent(Long key, Long keyVal) {
        // Noting to do here.
    }


    @Override
    public String toString() {
        return "{InstanceLockManager: " + _locks +  "}";
    }

    /**
     * Information about the lock state for a particular instance.
     * @author Maciej Szefler - m s z e f l e r @ g m a i l . c o m
     */
    private class InstanceInfo {
        final long iid;

        /** Thread that acquired the lock. */
        final Thread acquierer;

        /** Condition-Variable indicating that the lock has become available. */
        Condition available = _mutex.newCondition();


        InstanceInfo(long iid, Thread t) {
            this.iid = iid;
            this.acquierer = t;
        }

        @Override
        public String toString() {
            return "{Lock for Instance #" + iid +", acquired by " +  acquierer + "}";
        }
    }
}


