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

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