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

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;
    }

}
