/**
 * 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 com.twitter.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;
    }

}