/*******************************************************************************
 * Copyright (c) 2000, 2015 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.jres;

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.internal.ui.SWTFactory;
import org.eclipse.jdt.debug.ui.IJavaDebugUIConstants;
import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin;
import org.eclipse.jdt.internal.debug.ui.actions.ControlAccessibleListener;
import org.eclipse.jdt.launching.IVMInstall;
import org.eclipse.jdt.launching.IVMInstallType;
import org.eclipse.jdt.launching.JavaRuntime;
import org.eclipse.jdt.launching.VMStandin;
import org.eclipse.jdt.launching.environments.IExecutionEnvironment;
import org.eclipse.jdt.launching.environments.IExecutionEnvironmentsManager;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;

/**
 * A composite that displays installed JREs in a combo box, with a 'manage...'
 * button to modify installed JREs.
 * <p>
 * This block implements ISelectionProvider - it sends selection change events
 * when the checked JRE in the table changes, or when the "use default" button
 * check state changes.
 * </p>
 */
public class JREsComboBlock {

	public static final String PROPERTY_JRE = "PROPERTY_JRE"; //$NON-NLS-1$

	/**
	 * This block's control
	 */
	private Composite fControl;

	/**
	 * VMs being displayed
	 */
	private List<Object> fVMs = new ArrayList<>();

	/**
	 * The main control
	 */
	private Combo fCombo;

	// Action buttons
	private Button fManageButton;

	/**
	 * JRE change listeners
	 */
	private ListenerList<IPropertyChangeListener> fListeners = new ListenerList<>();

	/**
	 * Whether the default JRE should be in first position (if <code>false</code>, it becomes last).
	 */
	private boolean fDefaultFirst;

	/**
	 * Default JRE descriptor or <code>null</code> if none.
	 */
	private JREDescriptor fDefaultDescriptor = null;

	/**
	 * Specific JRE descriptor or <code>null</code> if none.
	 */
	private JREDescriptor fSpecificDescriptor = null;

	/**
	 * Default JRE radio button or <code>null</code> if none
	 */
	private Button fDefaultButton = null;

	/**
	 * Selected JRE radio button
	 */
	private Button fSpecificButton = null;

	/**
	 * The title used for the JRE block
	 */
	private String fTitle = null;

	/**
	 * Selected JRE profile radio button
	 */
	private Button fEnvironmentsButton = null;

	/**
	 * Combo box of JRE profiles
	 */
	private Combo fEnvironmentsCombo = null;

	private Button fManageEnvironmentsButton = null;

	// a path to an unavailable JRE
	private IPath fErrorPath;

	/**
	 * List of execution environments
	 */
	private List<Object> fEnvironments = new ArrayList<>();

	private IStatus fStatus = OK_STATUS;

	private static IStatus OK_STATUS = new Status(IStatus.OK, JDIDebugUIPlugin.getUniqueIdentifier(), 0, "", null); //$NON-NLS-1$

	/**
	 * Creates a JREs combo block.
	 *
	 * @param defaultFirst whether the default JRE should be in first position (if <code>false</code>, it becomes last)
	 */
	public JREsComboBlock(boolean defaultFirst) {
		fDefaultFirst= defaultFirst;
	}

	public void addPropertyChangeListener(IPropertyChangeListener listener) {
		fListeners.add(listener);
	}

	public void removePropertyChangeListener(IPropertyChangeListener listener) {
		fListeners.remove(listener);
	}

	private void firePropertyChange() {
		PropertyChangeEvent event = new PropertyChangeEvent(this, PROPERTY_JRE, null, getPath());
		for (IPropertyChangeListener listener : fListeners) {
			listener.propertyChange(event);
		}
	}

	/**
	 * Creates this block's control in the given control.
	 *
	 * @param anscestor containing control
	 */
	public void createControl(Composite ancestor) {
		fControl = SWTFactory.createComposite(ancestor, 1, 1, GridData.FILL_BOTH);
		if (fTitle == null) {
			fTitle = JREMessages.JREsComboBlock_3;
		}
		Group group = SWTFactory.createGroup(fControl, fTitle, 1, 1, GridData.FILL_HORIZONTAL);
		Composite comp = SWTFactory.createComposite(group, group.getFont(), 3, 1, GridData.FILL_BOTH, 0, 0);

		if (fDefaultFirst) {
			createDefaultJREControls(comp);
		}
		createEEControls(comp);
		createAlternateJREControls(comp);
		if (!fDefaultFirst) {
			createDefaultJREControls(comp);
		}
	}

	private void createEEControls(Composite comp) {
		fEnvironmentsButton = SWTFactory.createRadioButton(comp, JREMessages.JREsComboBlock_4);
		fEnvironmentsButton.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				if (fEnvironmentsButton.getSelection()) {
					fCombo.setEnabled(false);
					if (fEnvironmentsCombo.getText().length() == 0 && !fEnvironments.isEmpty()) {
						fEnvironmentsCombo.select(0);
					}
					fEnvironmentsCombo.setEnabled(true);
					if (fEnvironments.isEmpty()) {
						setError(JREMessages.JREsComboBlock_5);
					} else {
						setStatus(OK_STATUS);
					}
					firePropertyChange();
				}
			}
		});

		fEnvironmentsCombo = SWTFactory.createCombo(comp, SWT.DROP_DOWN | SWT.READ_ONLY, 1, null);
		fEnvironmentsCombo.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				setPath(JavaRuntime.newJREContainerPath(getEnvironment()));
				firePropertyChange();
			}
		});

		fManageEnvironmentsButton = SWTFactory.createPushButton(comp, JREMessages.JREsComboBlock_14, null);
		fManageEnvironmentsButton.addListener(SWT.Selection, new Listener() {
			@Override
			public void handleEvent(Event event) {
				showPrefPage(ExecutionEnvironmentsPreferencePage.ID);
			}
		});

		fillWithWorkspaceProfiles();
	}

	private void createAlternateJREControls(Composite comp) {
		String text = JREMessages.JREsComboBlock_1;
		if (fSpecificDescriptor != null) {
			text = fSpecificDescriptor.getDescription();
		}
		fSpecificButton = SWTFactory.createRadioButton(comp, text, 1);
		fSpecificButton.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				if (fSpecificButton.getSelection()) {
					fCombo.setEnabled(true);
					if (fCombo.getText().length() == 0 && !fVMs.isEmpty()) {
						fCombo.select(0);
					}
					if (fVMs.isEmpty()) {
						setError(JREMessages.JREsComboBlock_0);
					} else {
						setStatus(OK_STATUS);
					}
					fEnvironmentsCombo.setEnabled(false);
					firePropertyChange();
				}
			}
		});
		fCombo = SWTFactory.createCombo(comp, SWT.DROP_DOWN | SWT.READ_ONLY, 1, null);
		ControlAccessibleListener.addListener(fCombo, fSpecificButton.getText());
		fCombo.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				setStatus(OK_STATUS);
				firePropertyChange();
			}
		});

		fManageButton = SWTFactory.createPushButton(comp, JREMessages.JREsComboBlock_2, null);
		fManageButton.addListener(SWT.Selection, new Listener() {
			@Override
			public void handleEvent(Event event) {
				showPrefPage(JREsPreferencePage.ID);
			}
		});
		fillWithWorkspaceJREs();
	}

	private void createDefaultJREControls(Composite comp) {
		if (fDefaultDescriptor != null) {
			fDefaultButton = SWTFactory.createRadioButton(comp, fDefaultDescriptor.getDescription(), 3);
			fDefaultButton.addSelectionListener(new SelectionAdapter() {
				@Override
				public void widgetSelected(SelectionEvent e) {
					if (fDefaultButton.getSelection()) {
						setUseDefaultJRE();
						setStatus(OK_STATUS);
						firePropertyChange();
					}
				}
			});
		}
	}

	/**
	 * Opens the given preference page, and updates when closed.
	 *
	 * @param id pref page id
	 * @param page pref page
	 */
	private void showPrefPage(String id/*, IPreferencePage page*/) {
		IVMInstall prevJRE = getJRE();
		IExecutionEnvironment prevEnv = getEnvironment();
		JDIDebugUIPlugin.showPreferencePage(id);
		fillWithWorkspaceJREs();
		fillWithWorkspaceProfiles();
		restoreCombo(fVMs, prevJRE, fCombo);
		restoreCombo(fEnvironments, prevEnv, fEnvironmentsCombo);
		// update text
		setDefaultJREDescriptor(fDefaultDescriptor);
		if (isDefaultJRE()) {
			// reset in case default has changed
			setUseDefaultJRE();
		}
		setPath(getPath());
		firePropertyChange();
	}

	private void restoreCombo(List<Object> elements, Object element, Combo combo) {
		int index = -1;
		if (element != null) {
			index = elements.indexOf(element);
		}
		if (index >= 0) {
			combo.select(index);
		} else {
			combo.select(0);
		}
	}

	/**
	 * Returns this block's control
	 *
	 * @return control
	 */
	public Control getControl() {
		return fControl;
	}

	/**
	 * Sets the JREs to be displayed in this block
	 *
	 * @param vms JREs to be displayed
	 */
	protected void setJREs(List<VMStandin> jres) {
		fVMs.clear();
		fVMs.addAll(jres);
		// sort by name
		Collections.sort(fVMs, new Comparator<Object>() {
			@Override
			public int compare(Object o1, Object o2) {
				IVMInstall left = (IVMInstall)o1;
				IVMInstall right = (IVMInstall)o2;
				return left.getName().compareToIgnoreCase(right.getName());
			}

			@Override
			public boolean equals(Object obj) {
				return obj == this;
			}
		});
		// now make an array of names
		String[] names = new String[fVMs.size()];
		Iterator<Object> iter = fVMs.iterator();
		int i = 0;
		while (iter.hasNext()) {
			IVMInstall vm = (IVMInstall)iter.next();
			names[i] = vm.getName();
			i++;
		}
		fCombo.setItems(names);
		fCombo.setVisibleItemCount(Math.min(names.length, 20));
	}

	protected Shell getShell() {
		return getControl().getShell();
	}

	/**
	 * Selects a specific JRE based on type/name.
	 *
	 * @param vm JRE or <code>null</code>
	 */
	private void selectJRE(IVMInstall vm) {
		fSpecificButton.setSelection(true);
		fDefaultButton.setSelection(false);
		fEnvironmentsButton.setSelection(false);
		fCombo.setEnabled(true);
		fEnvironmentsCombo.setEnabled(false);
		if (vm != null) {
			int index = fVMs.indexOf(vm);
			if (index >= 0) {
				fCombo.select(index);
			}
		}
		firePropertyChange();
	}

	/**
	 * Selects a JRE based environment.
	 *
	 * @param env environment or <code>null</code>
	 */
	private void selectEnvironment(IExecutionEnvironment env) {
		fSpecificButton.setSelection(false);
		fDefaultButton.setSelection(false);
		fCombo.setEnabled(false);
		fEnvironmentsButton.setSelection(true);
		fEnvironmentsCombo.setEnabled(true);
		if (env != null) {
			int index = fEnvironments.indexOf(env);
			if (index >= 0) {
				fEnvironmentsCombo.select(index);
			}
		}
		firePropertyChange();
	}

	/**
	 * Returns the selected JRE or <code>null</code> if none.
	 *
	 * @return the selected JRE or <code>null</code> if none
	 */
	public IVMInstall getJRE() {
		int index = fCombo.getSelectionIndex();
		if (index >= 0) {
			return (IVMInstall)fVMs.get(index);
		}
		return null;
	}

	/**
	 * Returns the selected Environment or <code>null</code> if none.
	 *
	 * @return the selected Environment or <code>null</code> if none
	 */
	private IExecutionEnvironment getEnvironment() {
		int index = fEnvironmentsCombo.getSelectionIndex();
		if (index >= 0) {
			return (IExecutionEnvironment)fEnvironments.get(index);
		}
		return null;
	}

	/**
	 * Populates the JRE table with existing JREs defined in the workspace.
	 */
	protected void fillWithWorkspaceJREs() {
		// fill with JREs
		List<VMStandin> standins = new ArrayList<>();
		IVMInstallType[] types = JavaRuntime.getVMInstallTypes();
		for (int i = 0; i < types.length; i++) {
			IVMInstallType type = types[i];
			IVMInstall[] installs = type.getVMInstalls();
			for (int j = 0; j < installs.length; j++) {
				IVMInstall install = installs[j];
				standins.add(new VMStandin(install));
			}
		}
		setJREs(standins);
	}

	/**
	 * Populates the JRE profile combo with profiles defined in the workspace.
	 */
	protected void fillWithWorkspaceProfiles() {
		fEnvironments.clear();
		IExecutionEnvironment[] environments = JavaRuntime.getExecutionEnvironmentsManager().getExecutionEnvironments();
		for (int i = 0; i < environments.length; i++) {
			fEnvironments.add(environments[i]);
		}

		String[] names = new String[fEnvironments.size()];
		Iterator<Object> iter = fEnvironments.iterator();
		int i = 0;
		while (iter.hasNext()) {
			IExecutionEnvironment env = (IExecutionEnvironment)iter.next();
			IPath path = JavaRuntime.newJREContainerPath(env);
			IVMInstall install = JavaRuntime.getVMInstall(path);
			if (install != null) {
				names[i] = NLS.bind(JREMessages.JREsComboBlock_15, new String[]{env.getId(), install.getName()});
			} else {
				names[i] = NLS.bind(JREMessages.JREsComboBlock_16, new String[]{env.getId()});
			}
			i++;
		}
		fEnvironmentsCombo.setItems(names);
		fEnvironmentsCombo.setVisibleItemCount(Math.min(names.length, 20));
	}

	/**
	 * Sets the Default JRE Descriptor for this block.
	 *
	 * @param descriptor default JRE descriptor
	 */
	public void setDefaultJREDescriptor(JREDescriptor descriptor) {
		fDefaultDescriptor = descriptor;
		setButtonTextFromDescriptor(fDefaultButton, descriptor);
	}

	private void setButtonTextFromDescriptor(Button button, JREDescriptor descriptor) {
		if (button != null) {
			//update the description & JRE in case it has changed
			String currentText = button.getText();
			String newText = descriptor.getDescription();
			if (!newText.equals(currentText)) {
				button.setText(newText);
				fControl.layout();
			}
		}
	}

	/**
	 * Sets the specific JRE Descriptor for this block.
	 *
	 * @param descriptor specific JRE descriptor
	 */
	public void setSpecificJREDescriptor(JREDescriptor descriptor) {
		fSpecificDescriptor = descriptor;
		setButtonTextFromDescriptor(fSpecificButton, descriptor);
	}

	/**
	 * Returns whether the 'use default JRE' button is checked.
	 *
	 * @return whether the 'use default JRE' button is checked
	 */
	public boolean isDefaultJRE() {
		if (fDefaultButton != null) {
			return fDefaultButton.getSelection();
		}
		return false;
	}

	/**
	 * Sets this control to use the 'default' JRE.
	 */
	private void setUseDefaultJRE() {
		if (fDefaultDescriptor != null) {
			fDefaultButton.setSelection(true);
			fSpecificButton.setSelection(false);
			fEnvironmentsButton.setSelection(false);
			fCombo.setEnabled(false);
			fEnvironmentsCombo.setEnabled(false);
			firePropertyChange();
		}
	}

	/**
	 * Sets the title used for this JRE block
	 *
	 * @param title title for this JRE block
	 */
	public void setTitle(String title) {
		fTitle = title;
	}

	/**
	 * Refresh the default JRE description.
	 */
	public void refresh() {
		setDefaultJREDescriptor(fDefaultDescriptor);
	}

	/**
	 * Returns a classpath container path identifying the selected JRE.
	 *
	 * @return classpath container path or <code>null</code>
	 * @since 3.2
	 */
	public IPath getPath() {
		if (!getStatus().isOK() && fErrorPath != null) {
			return fErrorPath;
		}
		if (fEnvironmentsButton.getSelection()) {
			int index = fEnvironmentsCombo.getSelectionIndex();
			if (index >= 0) {
				IExecutionEnvironment env = (IExecutionEnvironment) fEnvironments.get(index);
				return JavaRuntime.newJREContainerPath(env);
			}
			return null;
		}
		if (fSpecificButton.getSelection()) {
			int index = fCombo.getSelectionIndex();
			if (index >= 0) {
				IVMInstall vm = (IVMInstall) fVMs.get(index);
				return JavaRuntime.newJREContainerPath(vm);
			}
			return null;
		}
		return JavaRuntime.newDefaultJREContainerPath();
	}

	/**
	 * Sets the selection based on the given container path and returns
	 * a status indicating if the selection was successful.
	 *
	 * @param containerPath
	 * @return status
	 */
	public void setPath(IPath containerPath) {
		fErrorPath = null;
		setStatus(OK_STATUS);
		if (JavaRuntime.newDefaultJREContainerPath().equals(containerPath)) {
			setUseDefaultJRE();
		} else {
			String envId = JavaRuntime.getExecutionEnvironmentId(containerPath);
			if (envId != null) {
				IExecutionEnvironmentsManager manager = JavaRuntime.getExecutionEnvironmentsManager();
				IExecutionEnvironment environment = manager.getEnvironment(envId);
				if (environment == null) {
					fErrorPath = containerPath;
					selectEnvironment(environment);
					setError(NLS.bind(JREMessages.JREsComboBlock_6, new String[]{envId}));
				} else {
					selectEnvironment(environment);
					IVMInstall[] installs = environment.getCompatibleVMs();
					if (installs.length == 0) {
						setError(NLS.bind(JREMessages.JREsComboBlock_7, new String[]{environment.getId()}));
					}
				}
			} else {
				IVMInstall install = JavaRuntime.getVMInstall(containerPath);
				if (install == null) {
					selectJRE(install);
					fErrorPath = containerPath;
					String installTypeId = JavaRuntime.getVMInstallTypeId(containerPath);
					if (installTypeId == null) {
						setError(JREMessages.JREsComboBlock_8);
					} else {
						IVMInstallType installType = JavaRuntime.getVMInstallType(installTypeId);
						if (installType == null) {
							setError(NLS.bind(JREMessages.JREsComboBlock_9, new String[]{installTypeId}));
						} else {
							String installName = JavaRuntime.getVMInstallName(containerPath);
							if (installName == null) {
								setError(NLS.bind(JREMessages.JREsComboBlock_10, new String[]{installType.getName()}));
							} else {
								setError(NLS.bind(JREMessages.JREsComboBlock_11, new String[]{installName, installType.getName()}));
							}
						}
					}
				} else {
					selectJRE(install);
					File location = install.getInstallLocation();
					if (location == null) {
						setError(JREMessages.JREsComboBlock_12);
					} else if (!location.exists()) {
						setError(JREMessages.JREsComboBlock_13);
					}
				}
			}
		}
	}

	private void setError(String message) {
		setStatus(new Status(IStatus.ERROR, JDIDebugUIPlugin.getUniqueIdentifier(),
				IJavaDebugUIConstants.INTERNAL_ERROR, message, null));
	}

	/**
	 * Returns the status of the JRE selection.
	 *
	 * @return status
	 */
	public IStatus getStatus() {
		return fStatus;
	}

	private void setStatus(IStatus status) {
		fStatus = status;
	}
}
