/*******************************************************************************
 * 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.clientserver;

import java.util.*;
import org.eclipse.persistence.testing.framework.*;
import org.eclipse.persistence.sessions.DatabaseLogin;

/**
 * Tests that a deadlock in sequencing does not occur.
 */
@SuppressWarnings("deprecation")
public class ClientServerSequenceDeadlockTest extends ClientServerConcurrentWriteTest {
    protected FIFO[] fifoArray;
    protected int[] clientStateArray;
    protected long[] clientLastActionTimeArray;
    protected int numObjects = 25;
    protected int doneClients;
    protected boolean deadlock;
    protected static final int THREAD_UNDEFINED = 0;
    protected static final int THREAD_RUNNING = 0;
    protected static final int THREAD_LOCKED = 1;
    protected static final int THREAD_EXITED = 2;
    protected static final long TIME_TO_PRESUME_DEADLOCK = 300000;

    /**
     *
     */
    public ClientServerSequenceDeadlockTest() {
        super();
        numObjects = 25;
        setDescription("Tests concurrent writing of objects of two types for sequencing deadlock");
        fifoArray = new FIFO[NUM_CLIENTS];
        clientStateArray = new int[NUM_CLIENTS];
        clientLastActionTimeArray = new long[NUM_CLIENTS];
    }

    /**
     *
     */
    public void reset() {
        for (int i = 0; i < getClients().size(); i++) {
            EmployeeSeqDeadlockClient client = (EmployeeSeqDeadlockClient)getClients().elementAt(i);
            if (clientStateArray[i] == THREAD_RUNNING) {
                client.stop();
            }
        }
        this.server.logout();
        setClients(new Vector());
    }

    /**
     *
     */
    public void setup() {
        this.login = (DatabaseLogin)getSession().getLogin().clone();
        // Workaround for DB2 bug (or feature?) causing test deadlock, see bug 3550940.
        if (this.login.getPlatform().isDB2()) {
            this.login.setTransactionIsolation(DatabaseLogin.TRANSACTION_SERIALIZABLE);
        }
        this.server = new Server(this.login);
        this.server.serverSession.getLogin().getDefaultSequence().setPreallocationSize(1);
        this.server.serverSession.setSessionLog(getSession().getSessionLog());
        this.server.login();
        this.server.copyDescriptors(getSession());
        for (int i = 0; i < NUM_CLIENTS; i++) {
            boolean createEmployees = (i % 2) == 0;
            fifoArray[i] = new FIFO(numObjects);
            getClients().addElement(new EmployeeSeqDeadlockClient(this.server, getSession(), "Client " + i, numObjects, createEmployees, fifoArray[i]));
            clientStateArray[i] = THREAD_UNDEFINED;
            clientLastActionTimeArray[i] = 0;
        }
        doneClients = 0;
        deadlock = false;
    }

    /**
     *
     */
    public void test() {
        for (int i = 0; i < NUM_CLIENTS; i++) {
            EmployeeSeqDeadlockClient client = (EmployeeSeqDeadlockClient)clients.elementAt(i);
            client.start();
            clientStateArray[i] = THREAD_RUNNING;
        }

        while (doneClients < NUM_CLIENTS) {
            for (int i = 0; i < NUM_CLIENTS; i++) {
                if (clientStateArray[i] == THREAD_RUNNING) {
                    if ((NUM_CLIENTS - doneClients) == 1) {
                        ((EmployeeClient)getClients().elementAt(i)).pleaseStop();
                    }
                    long currentTime = System.currentTimeMillis();
                    if (!fifoArray[i].isEmpty()) {
                        clientLastActionTimeArray[i] = currentTime;
                        int objectNumber = ((Integer)fifoArray[i].removeHead()).intValue();

                        //	                System.out.println("Client# = " + i + " object# =  " + objectNumber);
                        if ((objectNumber == numObjects) || (objectNumber == -1)) {
                            clientStateArray[i] = THREAD_EXITED;
                            doneClients++;
                            //    	                System.out.println("Client# = " + i + " EXITED");
                        }
                    } else {
                        if (clientLastActionTimeArray[i] == 0) {
                            clientLastActionTimeArray[i] = System.currentTimeMillis();
                        } else if ((currentTime - clientLastActionTimeArray[i]) >= TIME_TO_PRESUME_DEADLOCK) {
                            clientStateArray[i] = THREAD_LOCKED;
                            deadlock = true;
                            doneClients++;
                            ((Thread)getClients().elementAt(i)).stop();
                            //    	                System.out.println("Client# = " + i + " DEADLOCK");
                        }
                    }
                }
            }
        }
    }

    /**
     *
     */
    public void verify() {
        for (int i = 0; i < NUM_CLIENTS; i++) {
            EmployeeSeqDeadlockClient client = (EmployeeSeqDeadlockClient)clients.elementAt(i);
            if (client.anErrorOccurred()) {
                throw new TestErrorException("An exception " + client.getTestException() + " occurred in client " + client.toString());
            }
        }
        if (deadlock) {
            throw new TestErrorException("Looks like it's a deadlock");
        }
    }
}
