/*

   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.batik.util;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import org.apache.batik.test.AbstractTest;
import org.apache.batik.test.TestReport;

public class RunnableQueueTest extends AbstractTest {

    public int nThreads;
    public int activeThreads;
    public Random rand;
    public RunnableQueue rq;

    /**
     * Creates a new RunnableQueueTest.
     * @param nThreads number of runnables to queue
     */
    public RunnableQueueTest(int nThreads) {
        this.nThreads = nThreads;
    }
    public RunnableQueueTest(Integer nThreads) {
        this((nThreads==null)?10:nThreads.intValue());
    }
        
        /**
         * Returns this Test's name
         */
        public String getName() {
            return "RunnableQueue Stress Test";
        }

    /**
     * This method will only throw exceptions if some aspect
     * of the test's internal operation fails.
     */
    public TestReport runImpl() throws Exception {
        rq = RunnableQueue.createRunnableQueue();

        List l = new ArrayList(nThreads);
        rand = new Random(2345);

        // Two switch flickers to make things interesting...
        l.add(new SwitchFlicker());
        l.add(new SwitchFlicker());

        for (int i=0; i<nThreads; i++) {
            Runnable rqRable = new RQRable(i, rand.nextInt(50)+1);
            l.add(new TPRable(rq, i, rand.nextInt(4)+1,
                              rand.nextInt(500)+1, 20, rqRable));
        }

        synchronized (this) {
            ThreadPounder tp = new ThreadPounder(l);
            tp.start();
            activeThreads = nThreads;
            while (activeThreads != 0) {
                wait();
            }
        }

        System.exit(0);
        return null;
    }

    public class SwitchFlicker implements Runnable {
        public void run() {
            boolean suspendp, waitp;
            int time;
            while (true) {
                try {
                    synchronized (rand) {
                        suspendp = rand.nextBoolean();
                        waitp = rand.nextBoolean();
                        time  = rand.nextInt(500);
                    }
                    if (suspendp) {
                        // 1/2 of the time suspend, 1/2 time wait, 1/2 the
                        // time don't
                        rq.suspendExecution(waitp);
                        System.out.println("Suspended - " + 
                                           (waitp?"Wait":"Later"));
                        Thread.sleep(time/10);
                    } else {
                        // 1/2 the time resume
                        rq.resumeExecution();
                        System.out.println("Resumed");
                        Thread.sleep(time);
                    }
                } catch(InterruptedException ie) { }
            }
        }
    }

    public static final int INVOKE_LATER     = 1;
    public static final int INVOKE_AND_WAIT  = 2;
    public static final int PREEMPT_LATER    = 3;
    public static final int PREEMPT_AND_WAIT = 4;

    public class TPRable implements Runnable {

        RunnableQueue rq;
        int           idx;
        int           style;
        long          repeatDelay;
        int           count;
        Runnable      rqRable;

        TPRable(RunnableQueue rq, int idx, 
                int style,
                long    repeatDelay, int count,
                Runnable rqRable) {
            this.rq           = rq;
            this.idx          = idx;
            this.style        = style;
            this.repeatDelay  = repeatDelay;
            this.count        = count;
            this.rqRable      = rqRable;
        }

        public void run() {
            try {
                while (count-- != 0) {
                    switch (style) {
                    case INVOKE_LATER:
                        synchronized (rqRable) {
                            System.out.println("     InvL #" + idx);
                            rq.invokeLater(rqRable);
                            System.out.println("Done InvL #" + idx);
                            rqRable.wait();
                        }
                        break;
                    case INVOKE_AND_WAIT:
                        System.out.println("     InvW #" + idx);
                        rq.invokeAndWait(rqRable);
                        System.out.println("Done InvW #" + idx);
                        break;
                    case PREEMPT_LATER:
                        synchronized (rqRable) {
                            System.out.println("     PreL #" + idx);
                            rq.preemptLater(rqRable);
                            System.out.println("Done PreL #" + idx);
                            rqRable.wait();
                        }
                        break;
                    case PREEMPT_AND_WAIT:
                        System.out.println("     PreW #" + idx);
                        rq.preemptAndWait(rqRable);
                        System.out.println("Done PreW #" + idx);
                        break;
                    }
                        
                    if (repeatDelay < 0) 
                        break;
                    Thread.sleep(repeatDelay);
                }
            } catch (InterruptedException ie) {
            }
            synchronized(RunnableQueueTest.this) {
                activeThreads--;
                RunnableQueueTest.this.notify();
            }
        }
    }

    public static class RQRable implements Runnable {
        int  idx;
        long dur;

        RQRable(int idx, long dur) {
            this.idx = idx;
            this.dur = dur;
        }

        public void run() {
            try {
                System.out.println("      B Rable #" + idx);
                Thread.sleep(dur);
                System.out.println("      E Rable #" + idx);
                synchronized (this) {
                    notify();
                }
            } catch (InterruptedException ie) { }
        }
    }

    public static void main(String []args) {
        RunnableQueueTest rqt = new RunnableQueueTest(20);
        try {
            rqt.runImpl();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
