/*******************************************************************************
 * Copyright (c) 2004, 2012 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.internal.debug.ui.monitors;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.runtime.PlatformObject;
import org.eclipse.debug.core.DebugEvent;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.model.IDebugElement;
import org.eclipse.debug.core.model.IDebugTarget;
import org.eclipse.debug.core.model.IThread;
import org.eclipse.jdt.debug.core.IJavaObject;
import org.eclipse.jdt.debug.core.IJavaThread;

import com.sun.jdi.IncompatibleThreadStateException;

/**
 * Represent a Java thread in the threads and monitors model.
 */
public class JavaMonitorThread extends PlatformObject {

	/**
	 * The underlying thread.
	 */
	private IJavaThread fThread;

	private IThread fOriginalThread;

	/**
	 * The monitor this thread is waiting for.
	 */
	private JavaMonitor fContendedMonitor;
	/**
	 * The monitors owned by this thread.
	 */
	private JavaMonitor[] fOwnedMonitors= new JavaMonitor[0];
	/**
	 * Indicate if this thread is currently part of a deadlock.
	 */
	private boolean fIsInDeadlock;
	/**
	 * Indicate that the information for this thread need to be update, it
	 * may have changed.
	 */
	private boolean fToUpdate= true;

	/**
	 * List of JavaOwningThread and JavaWaitingThread associated with this thread.
	 */
	private List<IDebugElement> fElements= new ArrayList<>();

	/**
	 * JavaWaitingThread object used to return the JavaOwnedMonitor for this
	 * thread.
	 */
	private JavaWaitingThread fBaseWaitingThread;
	/**
	 * JavaOwningThread object uset to return the JavaWaitingMonitor for this
	 * thread.
	 */
	private JavaOwningThread fBaseOwningThread;

	public JavaMonitorThread(IJavaThread underlyingThread, IThread originalThread) {
		fThread= underlyingThread;
		fOriginalThread= originalThread;
	}

	public IJavaThread getThread() {
		return fThread;
	}

	public IThread getOriginalThread() {
		return fOriginalThread;
	}

	protected void setOriginalThread(IThread originalThread) {
		fOriginalThread= originalThread;
	}

	/**
	 * @see org.eclipse.debug.core.model.IDebugElement#getModelIdentifier()
	 */
	public String getModelIdentifier() {
		return fThread.getModelIdentifier();
	}

	/**
	 * @see org.eclipse.debug.core.model.IDebugElement#getDebugTarget()
	 */
	public IDebugTarget getDebugTarget() {
		return fThread.getDebugTarget();
	}

	/**
	 * @see org.eclipse.debug.core.model.IDebugElement#getLaunch()
	 */
	public ILaunch getLaunch() {
		return fThread.getLaunch();
	}

	/**
	 * @see org.eclipse.debug.core.model.ISuspendResume#isSuspended()
	 */
	public boolean isSuspended() {
		return fThread.isSuspended();
	}

	/**
	 * Returns the contended monitor to be used as a child
	 * of the underlying thread in the debug launch view.
	 */
	public JavaContendedMonitor getContendedMonitor() {
		if (fBaseOwningThread == null) {
			fBaseOwningThread= new JavaOwningThread(this, null);
		}
		return fBaseOwningThread.getContendedMonitor();
	}

	/**
	 * Returns the owned monitors to be used as children
	 * of the underlying thread in the debug launch view.
	 */
	public JavaOwnedMonitor[] getOwnedMonitors() {
		if (fBaseWaitingThread == null) {
			fBaseWaitingThread= new JavaWaitingThread(this, null);
		}
		return fBaseWaitingThread.getOwnedMonitors();
	}

	/**
	 * Returns the monitor this thread is waiting for.
	 */
	protected JavaMonitor getContendedMonitor0() {
		if (fToUpdate) {
			update();
		}
		return fContendedMonitor;
	}

	/**
	 * Returns the monitors owned by this thread.
	 */
	protected JavaMonitor[] getOwnedMonitors0() {
		if (fToUpdate) {
			update();
		}
		return fOwnedMonitors;
	}

	/**
	 * Update the information for this thread.
	 * @return <code>true</code> if the contended monitor or
	 * the owned monitors changed.
	 */
	private boolean update() {
		boolean changed= false;
		synchronized(this) {
			if (!fToUpdate) {
				return false;
			}
			try {
				// update the contended monitor
				IJavaObject contendedMonitor= fThread.getContendedMonitor();
				if (contendedMonitor == null) {
					changed= fContendedMonitor != null;
					fContendedMonitor= null;
				} else {
					changed= fContendedMonitor == null || !contendedMonitor.equals(fContendedMonitor.getMonitor());
					fContendedMonitor= ThreadMonitorManager.getDefault().getJavaMonitor(contendedMonitor);
				}
				// update the owned monitors
				IJavaObject[] ownedMonitors= fThread.getOwnedMonitors();
				if (ownedMonitors == null || ownedMonitors.length == 0) {
					// no owned monitor, not much to do
					changed= fOwnedMonitors != null && fOwnedMonitors.length != 0;
					fOwnedMonitors= new JavaMonitor[0];
				} else {
					JavaMonitor[] tmp= new JavaMonitor[ownedMonitors.length];
					ThreadMonitorManager threadMonitorManager= ThreadMonitorManager.getDefault();
					if (changed || fOwnedMonitors.length != ownedMonitors.length) {
						// if we know it changed, we can just create the new list.
						for (int i= 0; i < ownedMonitors.length; i++) {
							tmp[i]= threadMonitorManager.getJavaMonitor(ownedMonitors[i]);
						}
						changed= true;
					} else {
						// we need to check in the new list contains the same monitors as the
						// previous list
						int sameMonitor= 0;
						for (int i= 0; i < ownedMonitors.length; i++) {
							for (int j= 0; j < fOwnedMonitors.length; j++) {
								if (ownedMonitors[i].equals(fOwnedMonitors[i].getMonitor())) {
									sameMonitor++;
									break;
								}
							}
							tmp[i]= threadMonitorManager.getJavaMonitor(ownedMonitors[i]);
						}
						changed= sameMonitor != ownedMonitors.length;
					}
					fOwnedMonitors= tmp;
				}
			} catch (DebugException e) {
			    Throwable cause= e.getStatus().getException();
			    if (!(cause instanceof IncompatibleThreadStateException)) {
			        // IncompatibleThreadStateException are expected from Sun VMs
			        // if the thread is not suspended.
			        // For all other exceptions, null the values.
					fContendedMonitor= null;
					changed= fOwnedMonitors != null && fOwnedMonitors.length != 0;
					fOwnedMonitors= new JavaMonitor[0];
			    }
			} finally {
				fToUpdate= false;
			}
		}
		if (changed) {
			fireChangeEvent(DebugEvent.CONTENT);
		}
		return changed;
	}

	/**
	 * send a change event for theJavaWaitingThread and JavaOwningThread
	 * associated with this thread
	 */
	private void fireChangeEvent(int detail) {
		Object[] elements= fElements.toArray();
		List<Object> changedElement= new ArrayList<>();
		if (fOriginalThread != null) {
			changedElement.add(fOriginalThread);
		}
		for (int i= 0; i < elements.length; i++) {
			Object element= elements[i];
			// the two 'base' elements are not part of the hierarchy, they are
			// used to get the children of the Thread.
			if (element != fBaseOwningThread && element != fBaseWaitingThread) {
			    changedElement.add(element);
			}
		}
		DebugEvent[] changeEvents= new DebugEvent[changedElement.size()];
		int i= 0;
		for (Iterator<Object> iter= changedElement.iterator(); iter.hasNext();) {
		    changeEvents[i++]= new DebugEvent(iter.next(), DebugEvent.CHANGE, detail);
        }
		DebugPlugin.getDefault().fireDebugEventSet(changeEvents);
	}

	public synchronized void setToUpdate() {
		if (!fToUpdate) {
			fToUpdate= true;
			if (fContendedMonitor != null) {
				fContendedMonitor.setToUpdate();
			}
			if (fOwnedMonitors != null) {
				for (int i= 0; i < fOwnedMonitors.length; i++) {
					fOwnedMonitors[i].setToUpdate();
				}
			}
		}
	}

	protected void addElement(JavaOwningThread thread) {
		fElements.add(thread);
	}

	protected void addElement(JavaWaitingThread thread) {
		fElements.add(thread);
	}

	public void refresh() {
		if (fToUpdate && !update()) {
			if (fContendedMonitor != null) {
				fContendedMonitor.refresh();
			}
			for (int i= 0; i < fOwnedMonitors.length; i++) {
				fOwnedMonitors[i].refresh();
			}
		}
	}

	/**
	 * Indicate if this thread is currently part of a deadlock
	 */
	public boolean isInDeadlock() {
		return fIsInDeadlock;
	}
	/**
	 * Set this thread as being part of a deadlock.
	 */
	public void setInDeadlock(boolean isInDeadlock) {
		boolean oldValue= fIsInDeadlock;
		fIsInDeadlock = isInDeadlock;
		if (oldValue != isInDeadlock) {
			fireChangeEvent(DebugEvent.STATE);
		}
	}
}
