/**
 * 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.distributedlog;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.notification.Failure;

/**
 * Test Case for {@link TimedOutTestsListener}.
 */
public class TestTimedOutTestsListener {

    private static class Deadlock {
        private CyclicBarrier barrier = new CyclicBarrier(6);

        public Deadlock() {
            DeadlockThread[] dThreads = new DeadlockThread[6];

            Monitor a = new Monitor("a");
            Monitor b = new Monitor("b");
            Monitor c = new Monitor("c");
            dThreads[0] = new DeadlockThread("MThread-1", a, b);
            dThreads[1] = new DeadlockThread("MThread-2", b, c);
            dThreads[2] = new DeadlockThread("MThread-3", c, a);

            Lock d = new ReentrantLock();
            Lock e = new ReentrantLock();
            Lock f = new ReentrantLock();

            dThreads[3] = new DeadlockThread("SThread-4", d, e);
            dThreads[4] = new DeadlockThread("SThread-5", e, f);
            dThreads[5] = new DeadlockThread("SThread-6", f, d);

            // make them daemon threads so that the test will exit
            for (int i = 0; i < 6; i++) {
                dThreads[i].setDaemon(true);
                dThreads[i].start();
            }
        }

        class DeadlockThread extends Thread {
            private Lock lock1 = null;

            private Lock lock2 = null;

            private Monitor mon1 = null;

            private Monitor mon2 = null;

            private boolean useSync;

            DeadlockThread(String name, Lock lock1, Lock lock2) {
                super(name);
                this.lock1 = lock1;
                this.lock2 = lock2;
                this.useSync = true;
            }

            DeadlockThread(String name, Monitor mon1, Monitor mon2) {
                super(name);
                this.mon1 = mon1;
                this.mon2 = mon2;
                this.useSync = false;
            }

            public void run() {
                if (useSync) {
                    syncLock();
                } else {
                    monitorLock();
                }
            }

            private void syncLock() {
                lock1.lock();
                try {
                    try {
                        barrier.await();
                    } catch (Exception e) {
                    }
                    goSyncDeadlock();
                } finally {
                    lock1.unlock();
                }
            }

            private void goSyncDeadlock() {
                try {
                    barrier.await();
                } catch (Exception e) {
                }
                lock2.lock();
                throw new RuntimeException("should not reach here.");
            }

            private void monitorLock() {
                synchronized (mon1) {
                    try {
                        barrier.await();
                    } catch (Exception e) {
                    }
                    goMonitorDeadlock();
                }
            }

            private void goMonitorDeadlock() {
                try {
                    barrier.await();
                } catch (Exception e) {
                }
                synchronized (mon2) {
                    throw new RuntimeException(getName() + " should not reach here.");
                }
            }
        }

        class Monitor {
            String name;

            Monitor(String name) {
                this.name = name;
            }
        }

    }

    @Test(timeout = 500)
    public void testThreadDumpAndDeadlocks() throws Exception {
        new Deadlock();
        String s = null;
        while (true) {
            s = TimedOutTestsListener.buildDeadlockInfo();
            if (s != null) {
                break;
            }
            Thread.sleep(100);
        }

        Assert.assertEquals(3, countStringOccurrences(s, "BLOCKED"));

        Failure failure = new Failure(null, new Exception(TimedOutTestsListener.TEST_TIMED_OUT_PREFIX));
        StringWriter writer = new StringWriter();
        new TimedOutTestsListener(new PrintWriter(writer)).testFailure(failure);
        String out = writer.toString();

        Assert.assertTrue(out.contains("THREAD DUMP"));
        Assert.assertTrue(out.contains("DEADLOCKS DETECTED"));

        System.out.println(out);
    }

    private int countStringOccurrences(String s, String substr) {
        int n = 0;
        int index = 0;
        while ((index = s.indexOf(substr, index) + 1) != 0) {
            n++;
        }
        return n;
    }

}
