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

import java.util.ArrayList;
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.IDebugTarget;
import org.eclipse.jdt.debug.core.IJavaObject;
import org.eclipse.jdt.debug.core.IJavaThread;

/**
 * Represent a Java monitor in the threads and monitors model.
 */
public class JavaMonitor {

	/**
	 * The underlying object.
	 */
	private IJavaObject fMonitor;

	/**
	 * The thread which owns this monitor
	 */
	private JavaMonitorThread fOwningThread;
	/**
	 * The threads waiting for this monitor.
	 */
	private JavaMonitorThread[] fWaitingThreads= new JavaMonitorThread[0];
	/**
	 * Indicate if this monitor is currently part of a deadlock.
	 */
	private boolean fIsInDeadlock;
	/**
	 * Indicate that the information for this monitor need to be update, it
	 * may have changed.
	 */
	private boolean fToUpdate= true;

	/**
	 * The List of JavaContendedMonitor and JavaOwnedMonitor associated with this
	 * monitor.
	 */
	private List<PlatformObject> fElements= new ArrayList<>();

	public JavaMonitor(IJavaObject monitor) {
		fMonitor= monitor;
	}

	public IJavaObject getMonitor() {
		return fMonitor;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.model.IDebugElement#getDebugTarget()
	 */
	public IDebugTarget getDebugTarget() {
		return fMonitor.getDebugTarget();
	}
	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.model.IDebugElement#getLaunch()
	 */
	public ILaunch getLaunch() {
		return fMonitor.getLaunch();
	}
	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.model.IDebugElement#getModelIdentifier()
	 */
	public String getModelIdentifier() {
		return fMonitor.getModelIdentifier();
	}

	/**
	 * Returns the thread which owns this monitor, refresh the data
	 * first if need.
	 */
	protected JavaMonitorThread getOwningThread0() {
		if (fToUpdate) {
			update();
		}
		return fOwningThread;
	}

	/**
	 * Returns the threads waiting for this monitor, refresh the data
	 * first if need.
	 */
	protected JavaMonitorThread[] getWaitingThreads0() {
		if (fToUpdate) {
			update();
		}
		return fWaitingThreads;
	}

	/**
	 * Update the information for this monitor.
	 * @return <code>true</code> if the owning thread or
	 * the waiting threads changed.
	 */
	private boolean update() {
		boolean changed= false;
		boolean toRemove= false;
		ThreadMonitorManager threadMonitorManager= ThreadMonitorManager.getDefault();
		synchronized (this) {
			if (!fToUpdate) {
				return false;
			}
			try {
				if (fMonitor.isAllocated()) {
					// update the owning thread
					IJavaThread owningThread= fMonitor.getOwningThread();
					if (owningThread == null) {
						changed= fOwningThread != null;
						fOwningThread= null;
					} else {
						changed= fOwningThread == null || !owningThread.equals(fOwningThread.getThread());
						fOwningThread= ThreadMonitorManager.getDefault().getJavaMonitorThread(owningThread, null);
					}
					// update the waiting threads
					IJavaThread[] waitingThreads= fMonitor.getWaitingThreads();
					if (waitingThreads == null || waitingThreads.length == 0) {
						// if no waiting threads, not much to do
						changed= fWaitingThreads != null && fWaitingThreads.length != 0;
						fWaitingThreads= new JavaMonitorThread[0];
						toRemove= fOwningThread == null;
					} else {
						JavaMonitorThread[] tmp= new JavaMonitorThread[waitingThreads.length];
						if (changed || fWaitingThreads.length != waitingThreads.length) {
							// if we know it changed, we can just create the new list
							for (int i= 0; i < waitingThreads.length; i++) {
								tmp[i]= threadMonitorManager.getJavaMonitorThread(waitingThreads[i], null);
							}
							changed= true;
						} else {
							// we need to check in the new list contains the same threads as the
							// previous list
							int sameThread= 0;
							for (int i= 0; i < waitingThreads.length; i++) {
								for (int j= 0; j < fWaitingThreads.length; j++) {
									if (fWaitingThreads[i].getThread().equals(waitingThreads[i])) {
										sameThread++;
										break;
									}
								}
								tmp[i]= threadMonitorManager.getJavaMonitorThread(waitingThreads[i], null);
							}
							changed= sameThread != waitingThreads.length;
						}
						fWaitingThreads= tmp;
					}
				} else {
					toRemove= true;
				}
			} catch (DebugException e) {
				fOwningThread= null;
				fWaitingThreads= new JavaMonitorThread[0];
			} finally {
				fToUpdate= false;
			}
		}

		if (toRemove) {
			threadMonitorManager.removeJavaMonitor(this);
		} else if (changed) {
			fireChangeEvent(DebugEvent.CONTENT);
		}
		return changed;
	}

	/**
	 * Send a change event for theJavaContendedMonitor and JavaOwnedMonitor
	 * associated with this monitor
	 */
	private void fireChangeEvent(int detail) {
		Object[] elements= fElements.toArray();
		DebugEvent[] changeEvents= new DebugEvent[elements.length];
		for (int i= 0; i < elements.length; i++) {
			changeEvents[i]= new DebugEvent(elements[i], DebugEvent.CHANGE, detail);
		}
		DebugPlugin.getDefault().fireDebugEventSet(changeEvents);
	}

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

	protected void addElement(JavaOwnedMonitor monitor) {
		fElements.add(monitor);
	}

	protected void addElement(JavaContendedMonitor monitor) {
		fElements.add(monitor);
	}

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

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