/**
 * 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.curator.framework.recipes.locks;

import com.google.common.collect.Lists;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.imps.TestCleanState;
import org.apache.curator.framework.state.ConnectionState;
import org.apache.curator.framework.state.ConnectionStateListener;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.curator.test.BaseClassForTests;
import org.apache.curator.test.KillSession;
import org.apache.curator.test.TestingServer;
import org.apache.curator.test.Timing;
import org.apache.curator.utils.CloseableUtils;
import org.apache.curator.utils.ZKPaths;
import org.apache.zookeeper.CreateMode;
import org.testng.Assert;
import org.testng.annotations.Test;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;

public abstract class TestInterProcessMutexBase extends BaseClassForTests
{
    protected static final String LOCK_BASE_PATH = "/locks";

    private volatile CountDownLatch waitLatchForBar = null;
    private volatile CountDownLatch countLatchForBar = null;

    protected abstract InterProcessLock makeLock(CuratorFramework client);

    @Test
    public void testWaitingProcessKilledServer() throws Exception
    {
        final Timing timing = new Timing();
        final CuratorFramework client = CuratorFrameworkFactory.newClient(server.getConnectString(), timing.session(), timing.connection(), new ExponentialBackoffRetry(100, 3));
        try
        {
            client.start();

            final CountDownLatch latch = new CountDownLatch(1);
            ConnectionStateListener listener = new ConnectionStateListener()
            {
                @Override
                public void stateChanged(CuratorFramework client, ConnectionState newState)
                {
                    if ( newState == ConnectionState.LOST )
                    {
                        latch.countDown();
                    }
                }
            };
            client.getConnectionStateListenable().addListener(listener);

            final AtomicBoolean isFirst = new AtomicBoolean(true);
            ExecutorCompletionService<Object> service = new ExecutorCompletionService<Object>(Executors.newFixedThreadPool(2));
            for ( int i = 0; i < 2; ++i )
            {
                service.submit
                (
                    new Callable<Object>()
                    {
                        @Override
                        public Object call() throws Exception
                        {
                            InterProcessLock lock = makeLock(client);
                            lock.acquire();
                            try
                            {
                                if ( isFirst.compareAndSet(true, false) )
                                {
                                    timing.sleepABit();

                                    server.stop();
                                    Assert.assertTrue(timing.awaitLatch(latch));
                                    server.restart();
                                }
                            }
                            finally
                            {
                                try
                                {
                                    lock.release();
                                }
                                catch ( Exception e )
                                {
                                    // ignore
                                }
                            }
                            return null;
                        }
                    }
                );
            }

            for ( int i = 0; i < 2; ++i )
            {
                service.take().get(timing.forWaiting().milliseconds(), TimeUnit.MILLISECONDS);
            }
        }
        finally
        {
            TestCleanState.closeAndTestClean(client);
        }
    }

    @Test
    public void testKilledSession() throws Exception
    {
        final Timing timing = new Timing();

        CuratorFramework client = CuratorFrameworkFactory.newClient(server.getConnectString(), timing.session(), timing.connection(), new ExponentialBackoffRetry(100, 3));
        client.start();
        try
        {
            final InterProcessLock mutex1 = makeLock(client);
            final InterProcessLock mutex2 = makeLock(client);

            final Semaphore semaphore = new Semaphore(0);
            ExecutorCompletionService<Object> service = new ExecutorCompletionService<Object>(Executors.newFixedThreadPool(2));
            service.submit
                (
                    new Callable<Object>()
                    {
                        @Override
                        public Object call() throws Exception
                        {
                            mutex1.acquire();
                            semaphore.release();
                            Thread.sleep(1000000);
                            return null;
                        }
                    }
                );

            service.submit
                (
                    new Callable<Object>()
                    {
                        @Override
                        public Object call() throws Exception
                        {
                            mutex2.acquire();
                            semaphore.release();
                            Thread.sleep(1000000);
                            return null;
                        }
                    }
                );

            Assert.assertTrue(timing.acquireSemaphore(semaphore, 1));
            KillSession.kill(client.getZookeeperClient().getZooKeeper(), server.getConnectString());
            Assert.assertTrue(timing.acquireSemaphore(semaphore, 1));
        }
        finally
        {
            client.close();
        }
    }

    @Test
    public void testContainerCleanup() throws Exception
    {
        if ( !ZKPaths.hasContainerSupport() )
        {
            System.out.println("ZooKeeper version does not support Containers. Skipping test");
            return;
        }

        server.close();

        System.setProperty("container.checkIntervalMs", "10");
        try
        {
            server = new TestingServer();

            final int THREAD_QTY = 10;

            ExecutorService service = null;
            final CuratorFramework client = CuratorFrameworkFactory.newClient(server.getConnectString(), new ExponentialBackoffRetry(100, 3));
            try
            {
                client.start();

                List<Future<Object>> threads = Lists.newArrayList();
                service = Executors.newCachedThreadPool();
                for ( int i = 0; i < THREAD_QTY; ++i )
                {
                    Future<Object> t = service.submit
                    (
                        new Callable<Object>()
                        {
                            @Override
                            public Object call() throws Exception
                            {
                                InterProcessLock lock = makeLock(client);
                                lock.acquire();
                                try
                                {
                                    Thread.sleep(10);
                                }
                                finally
                                {
                                    lock.release();
                                }
                                return null;
                            }
                        }
                    );
                    threads.add(t);
                }

                for ( Future<Object> t : threads )
                {
                    t.get();
                }

                new Timing().sleepABit();

                Assert.assertNull(client.checkExists().forPath(LOCK_BASE_PATH));
            }
            finally
            {
                if ( service != null )
                {
                    service.shutdownNow();
                }
                CloseableUtils.closeQuietly(client);
            }
        }
        finally
        {
            System.clearProperty("container.checkIntervalMs");
        }
    }

    @Test
    public void testWithNamespace() throws Exception
    {
        CuratorFramework client = CuratorFrameworkFactory.builder().
            connectString(server.getConnectString()).
            retryPolicy(new ExponentialBackoffRetry(100, 3)).
            namespace("test").
            build();
        client.start();
        try
        {
            InterProcessLock mutex = makeLock(client);
            mutex.acquire(10, TimeUnit.SECONDS);
            Thread.sleep(100);
            mutex.release();
        }
        finally
        {
            TestCleanState.closeAndTestClean(client);
        }
    }

    @Test
    public void testReentrantSingleLock() throws Exception
    {
        final int THREAD_QTY = 10;

        CuratorFramework client = CuratorFrameworkFactory.newClient(server.getConnectString(), new ExponentialBackoffRetry(100, 3));
        client.start();
        try
        {
            final AtomicBoolean hasLock = new AtomicBoolean(false);
            final AtomicBoolean isFirst = new AtomicBoolean(true);
            final Semaphore semaphore = new Semaphore(1);
            final InterProcessLock mutex = makeLock(client);

            List<Future<Object>> threads = Lists.newArrayList();
            ExecutorService service = Executors.newCachedThreadPool();
            for ( int i = 0; i < THREAD_QTY; ++i )
            {
                Future<Object> t = service.submit
                    (
                        new Callable<Object>()
                        {
                            @Override
                            public Object call() throws Exception
                            {
                                semaphore.acquire();
                                mutex.acquire();
                                Assert.assertTrue(hasLock.compareAndSet(false, true));
                                try
                                {
                                    if ( isFirst.compareAndSet(true, false) )
                                    {
                                        semaphore.release(THREAD_QTY - 1);
                                        while ( semaphore.availablePermits() > 0 )
                                        {
                                            Thread.sleep(100);
                                        }
                                    }
                                    else
                                    {
                                        Thread.sleep(100);
                                    }
                                }
                                finally
                                {
                                    mutex.release();
                                    hasLock.set(false);
                                }
                                return null;
                            }
                        }
                    );
                threads.add(t);
            }

            for ( Future<Object> t : threads )
            {
                t.get();
            }
        }
        finally
        {
            TestCleanState.closeAndTestClean(client);
        }
    }

    @Test
    public void testReentrant2Threads() throws Exception
    {
        CuratorFramework client = CuratorFrameworkFactory.newClient(server.getConnectString(), new ExponentialBackoffRetry(100, 3));
        client.start();
        try
        {
            waitLatchForBar = new CountDownLatch(1);
            countLatchForBar = new CountDownLatch(1);

            final InterProcessLock mutex = makeLock(client);
            Executors.newSingleThreadExecutor().submit
                (
                    new Callable<Object>()
                    {
                        @Override
                        public Object call() throws Exception
                        {
                            Assert.assertTrue(countLatchForBar.await(10, TimeUnit.SECONDS));
                            try
                            {
                                mutex.acquire(10, TimeUnit.SECONDS);
                                Assert.fail();
                            }
                            catch ( Exception e )
                            {
                                // correct
                            }
                            finally
                            {
                                waitLatchForBar.countDown();
                            }
                            return null;
                        }
                    }
                );

            foo(mutex);
            Assert.assertFalse(mutex.isAcquiredInThisProcess());
        }
        finally
        {
            TestCleanState.closeAndTestClean(client);
        }
    }

    @Test
    public void testReentrant() throws Exception
    {
        CuratorFramework client = CuratorFrameworkFactory.newClient(server.getConnectString(), new ExponentialBackoffRetry(100, 3));
        client.start();
        try
        {
            InterProcessLock mutex = makeLock(client);
            foo(mutex);
            Assert.assertFalse(mutex.isAcquiredInThisProcess());
        }
        finally
        {
            TestCleanState.closeAndTestClean(client);
        }
    }

    private void foo(InterProcessLock mutex) throws Exception
    {
        mutex.acquire(10, TimeUnit.SECONDS);
        Assert.assertTrue(mutex.isAcquiredInThisProcess());
        bar(mutex);
        Assert.assertTrue(mutex.isAcquiredInThisProcess());
        mutex.release();
    }

    private void bar(InterProcessLock mutex) throws Exception
    {
        mutex.acquire(10, TimeUnit.SECONDS);
        Assert.assertTrue(mutex.isAcquiredInThisProcess());
        if ( countLatchForBar != null )
        {
            countLatchForBar.countDown();
            waitLatchForBar.await(10, TimeUnit.SECONDS);
        }
        snafu(mutex);
        Assert.assertTrue(mutex.isAcquiredInThisProcess());
        mutex.release();
    }

    private void snafu(InterProcessLock mutex) throws Exception
    {
        mutex.acquire(10, TimeUnit.SECONDS);
        Assert.assertTrue(mutex.isAcquiredInThisProcess());
        mutex.release();
        Assert.assertTrue(mutex.isAcquiredInThisProcess());
    }

    @Test
    public void test2Clients() throws Exception
    {
        CuratorFramework client1 = null;
        CuratorFramework client2 = null;
        try
        {
            client1 = CuratorFrameworkFactory.newClient(server.getConnectString(), new ExponentialBackoffRetry(100, 3));
            client2 = CuratorFrameworkFactory.newClient(server.getConnectString(), new ExponentialBackoffRetry(100, 3));
            client1.start();
            client2.start();

            final InterProcessLock mutexForClient1 = makeLock(client1);
            final InterProcessLock mutexForClient2 = makeLock(client2);

            final CountDownLatch latchForClient1 = new CountDownLatch(1);
            final CountDownLatch latchForClient2 = new CountDownLatch(1);
            final CountDownLatch acquiredLatchForClient1 = new CountDownLatch(1);
            final CountDownLatch acquiredLatchForClient2 = new CountDownLatch(1);

            final AtomicReference<Exception> exceptionRef = new AtomicReference<Exception>();

            ExecutorService service = Executors.newCachedThreadPool();
            Future<Object> future1 = service.submit
                (
                    new Callable<Object>()
                    {
                        @Override
                        public Object call() throws Exception
                        {
                            try
                            {
                                mutexForClient1.acquire(10, TimeUnit.SECONDS);
                                acquiredLatchForClient1.countDown();
                                latchForClient1.await(10, TimeUnit.SECONDS);
                                mutexForClient1.release();
                            }
                            catch ( Exception e )
                            {
                                exceptionRef.set(e);
                            }
                            return null;
                        }
                    }
                );
            Future<Object> future2 = service.submit
                (
                    new Callable<Object>()
                    {
                        @Override
                        public Object call() throws Exception
                        {
                            try
                            {
                                mutexForClient2.acquire(10, TimeUnit.SECONDS);
                                acquiredLatchForClient2.countDown();
                                latchForClient2.await(10, TimeUnit.SECONDS);
                                mutexForClient2.release();
                            }
                            catch ( Exception e )
                            {
                                exceptionRef.set(e);
                            }
                            return null;
                        }
                    }
                );

            while ( !mutexForClient1.isAcquiredInThisProcess() && !mutexForClient2.isAcquiredInThisProcess() )
            {
                Thread.sleep(1000);
                Assert.assertFalse(future1.isDone() && future2.isDone());
            }

            Assert.assertTrue(mutexForClient1.isAcquiredInThisProcess() != mutexForClient2.isAcquiredInThisProcess());
            Thread.sleep(1000);
            Assert.assertTrue(mutexForClient1.isAcquiredInThisProcess() || mutexForClient2.isAcquiredInThisProcess());
            Assert.assertTrue(mutexForClient1.isAcquiredInThisProcess() != mutexForClient2.isAcquiredInThisProcess());

            Exception exception = exceptionRef.get();
            if ( exception != null )
            {
                throw exception;
            }

            if ( mutexForClient1.isAcquiredInThisProcess() )
            {
                latchForClient1.countDown();
                Assert.assertTrue(acquiredLatchForClient2.await(10, TimeUnit.SECONDS));
                Assert.assertTrue(mutexForClient2.isAcquiredInThisProcess());
            }
            else
            {
                latchForClient2.countDown();
                Assert.assertTrue(acquiredLatchForClient1.await(10, TimeUnit.SECONDS));
                Assert.assertTrue(mutexForClient1.isAcquiredInThisProcess());
            }

            future1.get();
            future2.get();
        }
        finally
        {
            TestCleanState.closeAndTestClean(client1);
            TestCleanState.closeAndTestClean(client2);
        }
    }
}
