/*
 * 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.felix.dm.index.itest.tests;

import java.io.PrintStream;

import org.junit.Assert;

/**
 * Helper class to make sure that steps in a test happen in the correct order. Instantiate
 * this class and subsequently invoke <code>step(nr)</code> with steps starting at 1. You
 * can also have threads wait until you arrive at a certain step.
 * 
 * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
 */
public class Ensure {
    private final boolean DEBUG;
    private static long INSTANCE = 0;
    private static final int RESOLUTION = 100;
    private static PrintStream STREAM = System.out;
    int step = 0;
    private Throwable m_throwable;
    
    public Ensure() {
        this(true);
    }
    
    public Ensure(boolean debug) {
        DEBUG = debug;
        if (DEBUG) {
            INSTANCE++;
        }
    }

    public void setStream(PrintStream output) {
        STREAM = output;
    }
    
    /**
     * Mark this point as step <code>nr</code>.
     * 
     * @param nr the step we are in
     */
    public synchronized void step(int nr) {
        step++;
        Assert.assertEquals(nr, step);
        if (DEBUG) {
            String info = getLineInfo(3);
            STREAM.println("[Ensure " + INSTANCE + "] step " + step + " [" + currentThread() + "] " + info);
        }
        notifyAll();
    }

    private String getLineInfo(int depth) {
        StackTraceElement[] trace = Thread.currentThread().getStackTrace();
        String info = trace[depth].getClassName() + "." + trace[depth].getMethodName() + ":" + trace[depth].getLineNumber();
        return info;
    }
    
    /**
     * Mark this point as the next step.
     */
    public synchronized void step() {
        step++;
        if (DEBUG) {
            String info = getLineInfo(3);
            STREAM.println("[Ensure " + INSTANCE + "] next step " + step + " [" + currentThread() + "] " + info);
        }
        notifyAll();
    }

    /**
     * Wait until we arrive at least at step <code>nr</code> in the process, or fail if that
     * takes more than <code>timeout</code> milliseconds. If you invoke wait on a thread,
     * you are effectively assuming some other thread will invoke the <code>step(nr)</code>
     * method.
     * 
     * @param nr the step to wait for
     * @param timeout the number of milliseconds to wait
     */
    public synchronized void waitForStep(int nr, int timeout) {
        final int initialTimeout = timeout;
        if (DEBUG) {
            String info = getLineInfo(3);
            STREAM.println("[Ensure " + INSTANCE + "] waiting for step " + nr + " [" + currentThread() + "] " + info);
        }
        while (step < nr && timeout > 0) {
            try {
                wait(RESOLUTION);
                timeout -= RESOLUTION;
            }
            catch (InterruptedException e) {}
        }
        if (step < nr) {
            throw new IllegalStateException("Timed out waiting for " + initialTimeout + " ms for step " + nr + ", we are still at step " + step);
        }
        if (DEBUG) {
            String info = getLineInfo(3);
            STREAM.println("[Ensure " + INSTANCE + "] arrived at step " + nr + " [" + currentThread() + "] " + info);
        }
    }
    
    private String currentThread() {
        Thread thread = Thread.currentThread();
        return thread.getId() + " " + thread.getName();
    }
    
    public static Runnable createRunnableStep(final Ensure ensure, final int nr) {
        return new Runnable() { public void run() { ensure.step(nr); }};
    }
    
    public synchronized void steps(Steps steps) {
        steps.next(this);
    }
    
    /** 
     * Helper class for naming a list of step numbers. If used with the steps(Steps) method
     * you can define at which steps in time this point should be passed. That means you can
     * check methods that will get invoked multiple times during a test.
     */
    public static class Steps {
        private final int[] m_steps;
        private int m_stepIndex;

        /** 
         * Create a list of steps and initialize the step counter to zero.
         */
        public Steps(int... steps) {
            m_steps = steps;
            m_stepIndex = 0;
        }

        /**
         * Ensure we're at the right step. Will throw an index out of bounds exception if we enter this step more often than defined.
         */
        public void next(Ensure ensure) {
            ensure.step(m_steps[m_stepIndex++]);
        }
    }

    /**
     * Saves a thrown exception that occurred in a different thread. You can only save one exception
     * at a time this way.
     */
    public synchronized void throwable(Throwable throwable) {
        m_throwable = throwable;
    }

    /**
     * Throws a <code>Throwable</code> if one occurred in a different thread and that thread saved it
     * using the <code>throwable()</code> method.
     */
    public synchronized void ensure() throws Throwable {
        if (m_throwable != null) {
            throw m_throwable;
        }
    }
}
