/*******************************************************************************
 * Copyright (c) 1998, 2013 Oracle and/or its affiliates. All rights reserved.
 * This program and the accompanying materials are made available under the 
 * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 
 * which accompanies this distribution. 
 * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
 * and the Eclipse Distribution License is available at 
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * Contributors:
 *     Oracle - initial API and implementation from Oracle TopLink
 ******************************************************************************/  
package org.eclipse.persistence.testing.tests.simultaneous;

import java.io.*;
import java.util.*;
import org.eclipse.persistence.internal.helper.*;
import org.eclipse.persistence.sessions.*;
import org.eclipse.persistence.sessions.server.*;
import org.eclipse.persistence.exceptions.*;
import org.eclipse.persistence.testing.framework.*;
import org.eclipse.persistence.testing.framework.ui.SynchronizedTester;
import org.eclipse.persistence.testing.framework.ui.SynchronizedTestExecutor;

public class MultithreadTestCase extends AutoVerifyTestCase {
    protected TestCase[] test;
    protected int numberOfTests;
    protected boolean useSequenceConnectionPool = false;

    protected class TestEventListenerImpl implements junit.framework.TestListener {
        public static final int INITIAL = 0;
        public static final int STARTED = 1;
        public static final int FINISHED = 2;
        private int state;

        private TestEventListenerImpl() {
            state = INITIAL;
        }

        public void addError(junit.framework.Test test, Throwable error) {
        }

        public void addFailure(junit.framework.Test test, junit.framework.AssertionFailedError error) {
        }

        public void endTest(junit.framework.Test test) {
            state = FINISHED;
        }

        public void startTest(junit.framework.Test test) {
            state = STARTED;
        }

        public boolean isStarted() {
            return state == STARTED;
        }

        public boolean isFinished() {
            return state == FINISHED;
        }
    }
    ;

    protected TestEventListenerImpl[] testExecutorListener;
    protected TestExecutorWithClientSession[] testExecutorWithClientSession;
    protected SynchronizedTestExecutor[] testThread;

    protected class SynchronizedTesterImpl implements SynchronizedTester {
        public static final int INITIAL = 0;
        public static final int FINISHED = 1;
        private int state;
        private Throwable exception;

        private SynchronizedTesterImpl() {
            state = INITIAL;
        }

        public void finishedTest() {
            state = FINISHED;
        }

        public void notifyException(Throwable exception) {
            this.exception = exception;
        }

        public boolean isFinished() {
            return state == FINISHED;
        }

        public Throwable getException() {
            return exception;
        }
    }
    ;

    protected SynchronizedTesterImpl[] testThreadListener;
    protected Hashtable allowedExceptions;
    private Session originalSession;

    /**
     * Default constructor for MultithreadTestCase
     * Added to allow easier subclassing.  This constructor should only be used by subclasses.
     * addTests() must be called immediately after this constructor by the subclass
     */
    protected MultithreadTestCase() {
        super();
        setDescription("Runs several tests simultaneously");
        allowedExceptions = new Hashtable();
        addAllowedException("org.eclipse.persistence.exceptions.OptimisticLockException");
    }

    // MultithreadTestCase runs simultaneously each of the TestCases
    // passed in Vector tests.
    public MultithreadTestCase(Vector test) {
        this();
        setTests(test);
    }

    // If an exception occur in one of concurrently run tests,
    // MultithreadTestCase assigned this exception (and therefore status "Failed"),
    // unless the exception is on allowedExceptions list (see verify()).
    // By default, only org.eclipse.persistence.exceptions.OptimisticLockException
    // is on this list.
    // Use addAllowedException and removeAllowedException to add/remove
    // an exception to allowedExceptions list.
    public boolean addAllowedException(String exceptionClassName) {
        try {
            allowedExceptions.put(exceptionClassName, Class.forName(exceptionClassName));
            return true;
        } catch (ClassNotFoundException classNotFoundException) {
            return false;
        }
    }

    public void removeAllowedException(String exceptionClassName) {
        allowedExceptions.remove(exceptionClassName);
    }

    /**
     * Set the tests in this test case.  Refactored for easier subclassing.
     */
    public void setTests(Vector test) {
        if ((test != null) && !test.isEmpty()) {
            numberOfTests = test.size();

            this.test = new TestCase[numberOfTests];
            test.toArray(this.test);

            testExecutorWithClientSession = new TestExecutorWithClientSession[numberOfTests];
            testExecutorListener = new TestEventListenerImpl[numberOfTests];
            testThread = new SynchronizedTestExecutor[numberOfTests];
            testThreadListener = new SynchronizedTesterImpl[numberOfTests];
        }
    }

    protected void setup() {
        getSession().getIdentityMapAccessor().initializeAllIdentityMaps();
        setupSession();

        for (int i = 0; i < numberOfTests; i++) {
            // Need this for proper idention of while printing test results
            test[i].setContainer(this);

            // To run a test we need an executor.
            // To run simultaneously several tests we need a personal
            // executor for each of them.
            // For each test an instance of a subclass of TestExecutor is created:
            // TestExecutorWithClientSession:
            //   carries clientSession;
            //   readdresses some method calls to its parent - TestExecutor, disallows other ones;
            testExecutorWithClientSession[i] = new TestExecutorWithClientSession(getExecutor());

            // That's an optional TestExecutorListener.
            // Currently not used.
            testExecutorListener[i] = new TestEventListenerImpl();
            testExecutorWithClientSession[i].setListener(testExecutorListener[i]);

            // That's a ThreadListener - it receives call backs from
            // the thread - currently used is testFinished notification.
            testThreadListener[i] = new SynchronizedTesterImpl();

            test[i].setExecutor(testExecutorWithClientSession[i]);
                 
            // That's a personal thread for the test
            testThread[i] = new SynchronizedTestExecutor(testExecutorWithClientSession[i], test[i], testThreadListener[i]);
            testThread[i].setName("Test Thread " + i);
        }
    }

    protected void setupSession() {
        originalSession = getSession();
        Session newSession = setupNewSession(originalSession, useSequenceConnectionPool);
        getExecutor().setSession(newSession);
    }

    // In order for MultithreadTestCase to run, it needs
    // a ServerSession to be returned by TestExecutor.getSession().
    // This method takes a session originally held by TestExecutor 
    // (typically DatabaseSession) - and returns the ServerSession
    // which should be set as a Session into TestExecutor.
    // The possible variants:
    //   case originalSession is a ServerSession - will use it as a new session;
    //   case originalSession is a ClientSession - will use its parent as a new session.
    //
    // This is a static method so that it could be used by other classes.
    //
    // Use resetOriginalSession before setting the originalSession
    // back into TestExecutor.
    static public Session setupNewSession(Session originalSession, boolean useSequenceConnectionPool) {
        // Note that because ServerSession.isDatabaseSession() returns true
        // it is important to call isServerSession() before
        // isDatabaseSession() is called 
        if (originalSession.isServerSession()) {
            return originalSession;
        } else if (originalSession.isDatabaseSession()) {
            // The following piece mostly copied from ClientServerTestModel
            // The only thing added is initializePreallocatedSequences() -
            // don't want to re-use the sequence numbers allocated by originalSession.
            DatabaseSession databaseSession = (DatabaseSession)originalSession;
            DatabaseLogin login = (DatabaseLogin)databaseSession.getLogin().clone();
            databaseSession.getSequencingControl().initializePreallocated();
            Server serverSession = new ServerSession(login, 5, 5);
            serverSession.setSessionLog(databaseSession.getSessionLog());
            if (useSequenceConnectionPool) {
                serverSession.getSequencingControl().setShouldUseSeparateConnection(true);
            } else {
                serverSession.getSequencingControl().setShouldUseSeparateConnection(false);                
            }
            serverSession.login();

            Vector descriptors = new Vector();
            for (Iterator iterator = databaseSession.getDescriptors().values().iterator();
                     iterator.hasNext();) {
                descriptors.addElement(iterator.next());
            }
            serverSession.addDescriptors(descriptors);

            return serverSession;
        } else if (originalSession.isClientSession()) {
            ClientSession clientSession = (ClientSession)originalSession;
            ServerSession serverSession = clientSession.getParent();
            return serverSession;
        } else {
            // Should never happen
            return null;
        }
    }

    // Note that currently there is nothing done
    // to resolve possible deadlocks.
    protected void test() {
        //run test threads
        for (int i = 0; i < numberOfTests; i++) {
            testThread[i].start();
        }

        //waiting for test threads to complete
        int numberOfCompletedTests;
        do {
            numberOfCompletedTests = 0;
            for (int i = 0; i < numberOfTests; i++) {
                if (testThreadListener[i].isFinished()) {
                    numberOfCompletedTests++;
                }
            }
        } while (numberOfCompletedTests < numberOfTests);
    }

    protected void verify() {
        EclipseLinkException exception = null;
        for (int i = 0; (i < numberOfTests) && (exception == null); i++) {
            exception = test[i].getTestResult().getException();
            if (exception != null) {
                for (Enumeration enumtr = allowedExceptions.elements();
                         enumtr.hasMoreElements() && (exception != null);) {
                    if (((Class)(enumtr.nextElement())).isInstance(exception)) {
                        exception = null;
                    }
                }
                if (exception != null) {
                    setTestException(exception);
                }
            }
        }
    }

    // the originalSession != null check is needed
    // in case reset is called more than once -
    // which may happen in case of test failure due to
    // the resent changes in AutoVerifyTestCase.
    public void reset() {
        getSession().getIdentityMapAccessor().initializeAllIdentityMaps();
        if (originalSession != null) {
            resetSession();
        }
    }

    protected void resetSession() {
        resetOriginalSession(originalSession, getSession());
        getExecutor().setSession(originalSession);
        originalSession = null;
    }

    static public void resetOriginalSession(Session originalSession, Session newSession) {
        // Note that because ServerSession.isDatabaseSession() returns true
        // it is important to call isServerSession() before
        // isDatabaseSession() is called 
        if (originalSession.isServerSession()) {
            // Assuming that originalSession == newSession
            // (see setNewSession(..))
            return;
        } else if (originalSession.isDatabaseSession()) {
            ((DatabaseSession)newSession).logout();

            DatabaseSession databaseSession = (DatabaseSession)originalSession;

            // Is this necessary? Don't know.
            // Just copied it from ClientServerTestModel
            databaseSession.logout();
            databaseSession.login();
        }
    }

    public void logResult(Writer log) {
        super.logResult(log);

        for (int i = 0; i < numberOfTests; i++) {
            try {
                log.write(org.eclipse.persistence.internal.helper.Helper.cr() + Helper.getTabs(getNestedCounter() + 1) + "Test Thread " + i);
            } catch (IOException exception) {
            }
            test[i].logResult(log);
        }
    }

    public void useSequenceConnectionPool() {
        useSequenceConnectionPool = true;
    }
}
