/*******************************************************************************
 * Copyright (c) 2000, 2017 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.ant.internal.ui.preferences;

import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import org.eclipse.ant.core.IAntClasspathEntry;
import org.eclipse.ant.internal.core.IAntCoreConstants;
import org.eclipse.ant.internal.ui.AntUIPlugin;
import org.eclipse.ant.internal.ui.IAntUIConstants;
import org.eclipse.ant.internal.ui.IAntUIPreferenceConstants;
import org.eclipse.ant.internal.ui.launchConfigurations.VariableInputDialog;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.variables.VariablesPlugin;
import org.eclipse.jdt.ui.wizards.BuildPathDialogAccess;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.dialogs.MessageDialogWithToggle;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.DirectoryDialog;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Tree;

public class AntClasspathBlock {

	private static final String[] TOOLS = new String[] { "tools.jar" }; //$NON-NLS-1$

	private TreeViewer treeViewer;
	private AntClasspathContentProvider antContentProvider;

	private Button upButton;
	private Button downButton;
	private Button removeButton;

	private AntClasspathLabelProvider labelProvider = new AntClasspathLabelProvider(this);
	private Button addFolderButton;
	private Button addJARButton;
	private Button addExternalJARButton;
	private Button addVariableButton;
	private Button antHomeButton;

	private String antHome;

	private IDialogSettings dialogSettings = AntUIPlugin.getDefault().getDialogSettings();

	private IAntBlockContainer container;

	private int validated = 2;

	private IClasspathEntry currentParent;

	private SelectionListener selectionListener = new SelectionAdapter() {
		@Override
		public void widgetSelected(SelectionEvent e) {
			Object source = e.getSource();
			if (source == addJARButton) {
				addJars();
			} else if (source == addExternalJARButton) {
				addExternalJars();
			} else if (source == addFolderButton) {
				addFolder();
			} else if (upButton == source) {
				handleMoveUp();
			} else if (downButton == source) {
				handleMoveDown();
			} else if (removeButton == source) {
				remove();
			} else if (addVariableButton == source) {
				addVariable();
			} else if (antHomeButton == source) {
				browseAntHome();
			}
		}
	};

	public void setContainer(IAntBlockContainer container) {
		this.container = container;
	}

	private void addButtonsToButtonGroup(Composite parent) {

		addJARButton = container.createPushButton(parent, AntPreferencesMessages.AntClasspathBlock_addJarButtonTitle);
		addJARButton.addSelectionListener(selectionListener);

		addExternalJARButton = container.createPushButton(parent, AntPreferencesMessages.AntClasspathBlock_42);
		addExternalJARButton.addSelectionListener(selectionListener);
		addFolderButton = container.createPushButton(parent, AntPreferencesMessages.AntClasspathBlock_addFolderButtonTitle);
		addFolderButton.addSelectionListener(selectionListener);

		addVariableButton = container.createPushButton(parent, AntPreferencesMessages.AntClasspathBlock_2);
		addVariableButton.addSelectionListener(selectionListener);

		antHomeButton = container.createPushButton(parent, AntPreferencesMessages.AntClasspathBlock_30);
		antHomeButton.addSelectionListener(selectionListener);

		removeButton = container.createPushButton(parent, AntPreferencesMessages.AntClasspathBlock_removeButtonTitle);
		removeButton.addSelectionListener(selectionListener);

		upButton = container.createPushButton(parent, AntPreferencesMessages.AntClasspathBlock_upButtonTitle);
		upButton.addSelectionListener(selectionListener);
		downButton = container.createPushButton(parent, AntPreferencesMessages.AntClasspathBlock_downButtonTitle);
		downButton.addSelectionListener(selectionListener);
	}

	/**
	 * Returns the selected items in the list, in the order they are displayed.
	 * 
	 * @return targets for an action
	 */
	private List<IAntClasspathEntry> getOrderedSelection(IClasspathEntry parent) {
		List<IAntClasspathEntry> targets = new ArrayList<>();
		List<?> selection = ((IStructuredSelection) treeViewer.getSelection()).toList();
		IAntClasspathEntry[] entries = parent.getEntries();
		for (int i = 0; i < entries.length; i++) {
			IAntClasspathEntry target = entries[i];
			if (selection.contains(target)) {
				targets.add(target);
			}
		}
		return targets;
	}

	private void handleMoveDown() {
		List<IAntClasspathEntry> targets = getOrderedSelection(currentParent);
		List<IAntClasspathEntry> list = new ArrayList<>(Arrays.asList(currentParent.getEntries()));
		int bottom = list.size() - 1;
		int index = 0;
		for (int i = targets.size() - 1; i >= 0; i--) {
			IAntClasspathEntry target = targets.get(i);
			index = list.indexOf(target);
			if (index < bottom) {
				bottom = index + 1;
				IAntClasspathEntry temp = list.get(bottom);
				list.set(bottom, target);
				list.set(index, temp);
			}
			bottom = index;
		}
		finishMove(list);
	}

	private void finishMove(List<IAntClasspathEntry> list) {
		AntClasspathContentProvider viewerContentProvider = (AntClasspathContentProvider) treeViewer.getContentProvider();
		viewerContentProvider.setEntries(currentParent, list);
		treeViewer.refresh();
		treeViewer.setSelection(treeViewer.getSelection());
		updateContainer();
	}

	private void handleMoveUp() {
		List<IAntClasspathEntry> targets = getOrderedSelection(currentParent);
		int top = 0;
		int index = 0;
		List<IAntClasspathEntry> list = new ArrayList<>(Arrays.asList(currentParent.getEntries()));
		Iterator<IAntClasspathEntry> entries = targets.iterator();
		while (entries.hasNext()) {
			IAntClasspathEntry target = entries.next();
			index = list.indexOf(target);
			if (index > top) {
				top = index - 1;
				IAntClasspathEntry temp = list.get(top);
				list.set(top, target);
				list.set(index, temp);
			}
			top = index;
		}

		finishMove(list);
	}

	private void remove() {
		AntClasspathContentProvider viewerContentProvider = (AntClasspathContentProvider) treeViewer.getContentProvider();
		IStructuredSelection sel = (IStructuredSelection) treeViewer.getSelection();
		viewerContentProvider.remove(sel);
		updateContainer();
	}

	/**
	 * Allows the user to enter a folder as a classpath.
	 */
	private void addFolder() {
		String lastUsedPath = dialogSettings.get(IAntUIConstants.DIALOGSTORE_LASTFOLDER);
		if (lastUsedPath == null) {
			lastUsedPath = ResourcesPlugin.getWorkspace().getRoot().getLocation().toOSString();
		}
		DirectoryDialog dialog = new DirectoryDialog(treeViewer.getControl().getShell(), SWT.SHEET);
		dialog.setMessage(AntPreferencesMessages.AntClasspathBlock_1);
		dialog.setFilterPath(lastUsedPath);
		String result = dialog.open();
		if (result != null) {
			try {
				URL url = new URL(IAntCoreConstants.FILE_PROTOCOL + result + "/"); //$NON-NLS-1$ ;
				((AntClasspathContentProvider) treeViewer.getContentProvider()).add(currentParent, url);
			}
			catch (MalformedURLException e) {
				// do nothing
			}
		}
		treeViewer.setSelection(treeViewer.getSelection());
		dialogSettings.put(IAntUIConstants.DIALOGSTORE_LASTFOLDER, result);
		updateContainer();
	}

	private void addExternalJars() {
		String lastUsedPath = dialogSettings.get(IAntUIConstants.DIALOGSTORE_LASTEXTJAR);
		if (lastUsedPath == null) {
			lastUsedPath = ResourcesPlugin.getWorkspace().getRoot().getLocation().toOSString();
		}
		FileDialog dialog = new FileDialog(treeViewer.getControl().getShell(), SWT.MULTI | SWT.SHEET);
		dialog.setFilterExtensions(new String[] { "*.jar;*.zip" }); //$NON-NLS-1$
		dialog.setFilterPath(lastUsedPath);

		String result = dialog.open();
		if (result == null) {
			return;
		}
		IPath filterPath = new Path(dialog.getFilterPath());
		String[] results = dialog.getFileNames();
		AntClasspathContentProvider contentProvider = (AntClasspathContentProvider) treeViewer.getContentProvider();
		contentProvider.setRefreshEnabled(false);
		for (int i = 0; i < results.length; i++) {
			String jarName = results[i];
			try {
				IPath path = filterPath.append(jarName).makeAbsolute();
				URL url = new URL(IAntCoreConstants.FILE_PROTOCOL + path.toOSString());
				contentProvider.add(currentParent, url);
			}
			catch (MalformedURLException e) {
				// do nothing
			}
		}
		contentProvider.setRefreshEnabled(true);

		treeViewer.setSelection(treeViewer.getSelection());
		dialogSettings.put(IAntUIConstants.DIALOGSTORE_LASTEXTJAR, filterPath.toOSString());
		updateContainer();
	}

	private void addJars() {
		List<IAntClasspathEntry> allEntries = new ArrayList<>();
		if (currentParent != null) {
			allEntries.addAll(Arrays.asList(currentParent.getEntries()));
		} else {
			IAntClasspathEntry[] entries = antContentProvider.getModel().getEntries(ClasspathModel.USER);
			if (entries != null) {
				allEntries.addAll(Arrays.asList(entries));
			}
		}

		List<IPath> selectedPaths = new ArrayList<>(allEntries.size());
		Iterator<IAntClasspathEntry> iterator = allEntries.iterator();
		while (iterator.hasNext()) {
			IAntClasspathEntry entry = iterator.next();
			URL url = entry.getEntryURL();
			if (url != null) {
				String file = url.getFile();
				if (file != null && file.length() > 0) {
					IFile[] files = ResourcesPlugin.getWorkspace().getRoot().findFilesForLocationURI(new Path(file).toFile().toURI());
					for (int i = 0; i < files.length; i++) {
						selectedPaths.add(files[i].getFullPath());
					}
				}
			}
		}

		IPath[] paths = BuildPathDialogAccess.chooseJAREntries(treeViewer.getControl().getShell(), null, selectedPaths.toArray(new IPath[selectedPaths.size()]));

		if (paths != null && paths.length > 0) {
			AntClasspathContentProvider contentProvider = (AntClasspathContentProvider) treeViewer.getContentProvider();
			contentProvider.setRefreshEnabled(false);
			for (int i = 0; i < paths.length; i++) {
				String varExpression = VariablesPlugin.getDefault().getStringVariableManager().generateVariableExpression("workspace_loc", paths[i].toString()); //$NON-NLS-1$
				contentProvider.add(currentParent, varExpression);
			}
			contentProvider.setRefreshEnabled(true);
			updateContainer();
		}
	}

	private void updateContainer() {
		validated = 0;
		container.update();
	}

	/**
	 * Creates the group which will contain the buttons.
	 */
	private void createButtonGroup(Composite top) {
		Composite buttonGroup = new Composite(top, SWT.NONE);
		GridLayout layout = new GridLayout();
		layout.marginHeight = 0;
		layout.marginWidth = 0;
		buttonGroup.setLayout(layout);
		buttonGroup.setLayoutData(new GridData(GridData.FILL_VERTICAL));
		buttonGroup.setFont(top.getFont());

		addButtonsToButtonGroup(buttonGroup);
	}

	private void createClasspathTree(Composite parent) {
		Tree tree = new Tree(parent, SWT.MULTI | SWT.FULL_SELECTION | SWT.BORDER);
		GridData data = new GridData(GridData.FILL_BOTH);
		data.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH;
		data.heightHint = tree.getItemHeight();
		tree.setLayoutData(data);
		tree.setFont(parent.getFont());

		tree.addKeyListener(new KeyAdapter() {
			@Override
			public void keyPressed(KeyEvent event) {
				if (event.character == SWT.DEL && event.stateMask == 0) {
					remove();
				}
			}
		});

		antContentProvider = new AntClasspathContentProvider();
		treeViewer = new TreeViewer(tree);
		treeViewer.setContentProvider(antContentProvider);
		treeViewer.setLabelProvider(labelProvider);
		treeViewer.addSelectionChangedListener(new ISelectionChangedListener() {
			@Override
			public void selectionChanged(SelectionChangedEvent event) {
				tableSelectionChanged((IStructuredSelection) event.getSelection(), (AntClasspathContentProvider) treeViewer.getContentProvider());
			}
		});
	}

	public void createContents(Composite parent) {
		createClasspathTree(parent);
		createButtonGroup(parent);

		tableSelectionChanged((IStructuredSelection) treeViewer.getSelection(), antContentProvider);
	}

	private void tableSelectionChanged(IStructuredSelection selection, AntClasspathContentProvider contentProvider) {

		boolean notEmpty = !selection.isEmpty();
		boolean first = !notEmpty;
		boolean last = !notEmpty;
		boolean canRemove = true;
		boolean canAdd = notEmpty;
		boolean canMove = true;
		if (!resolveCurrentParent(selection)) {
			// selection contains elements from multiple parents
			canAdd = false;
			canMove = false;
			canRemove = false;
		} else {
			Iterator<?> selected = selection.iterator();
			while (selected.hasNext()) {
				IClasspathEntry element = (IClasspathEntry) selected.next();

				if (element instanceof GlobalClasspathEntries) {
					GlobalClasspathEntries global = (GlobalClasspathEntries) element;
					canRemove = global.canBeRemoved();
					canAdd = global.getType() != ClasspathModel.CONTRIBUTED;
					canMove = false;
				}
				IClasspathEntry parent = element.getParent();
				if (parent instanceof GlobalClasspathEntries) {
					canAdd = ((GlobalClasspathEntries) parent).getType() != ClasspathModel.CONTRIBUTED;
					canRemove = canAdd;
					canMove = canAdd;
				}
				Object[] childEntries = contentProvider.getChildren(parent);
				List<Object> entries = Arrays.asList(childEntries);
				int lastEntryIndex = entries.size() - 1;
				if (!first && entries.indexOf(element) == 0) {
					first = true;
				}
				if (!last && entries.indexOf(element) == lastEntryIndex) {
					last = true;
				}
			}
		}

		addJARButton.setEnabled(canAdd);
		addExternalJARButton.setEnabled(canAdd);
		addFolderButton.setEnabled(canAdd);
		addVariableButton.setEnabled(canAdd);
		removeButton.setEnabled(notEmpty && canRemove);
		upButton.setEnabled(canMove && !first);
		downButton.setEnabled(canMove && !last);
	}

	private boolean resolveCurrentParent(IStructuredSelection selection) {
		currentParent = null;
		Iterator<?> selected = selection.iterator();

		while (selected.hasNext()) {
			Object element = selected.next();
			if (element instanceof ClasspathEntry) {
				IClasspathEntry parent = ((IClasspathEntry) element).getParent();
				if (currentParent != null) {
					if (!currentParent.equals(parent)) {
						return false;
					}
				} else {
					currentParent = parent;
				}
			} else {
				if (currentParent != null) {
					if (!currentParent.equals(element)) {
						return false;
					}
				} else {
					currentParent = (IClasspathEntry) element;
				}
			}
		}
		return true;
	}

	private File validateAntHome(String path) {
		File rootDir = null;
		boolean invalid = true;
		if (path.length() > 0) {
			rootDir = new File(path, "lib"); //$NON-NLS-1$
			File parentDir = rootDir.getParentFile();
			if (parentDir == null || !parentDir.exists()) {
				container.setErrorMessage(AntPreferencesMessages.AntClasspathBlock_56);
			} else if (!rootDir.exists()) {
				container.setErrorMessage(AntPreferencesMessages.AntClasspathBlock_7);
			} else {
				invalid = false;
			}
		} else {
			container.setErrorMessage(AntPreferencesMessages.AntClasspathBlock_57);
		}
		if (invalid) {
			setValidated();
			return null;
		}
		container.setErrorMessage(null);
		return rootDir;
	}

	private void browseAntHome() {
		String lastUsedPath = dialogSettings.get(IAntUIConstants.DIALOGSTORE_LASTANTHOME);
		if (lastUsedPath == null) {
			lastUsedPath = ResourcesPlugin.getWorkspace().getRoot().getLocation().toOSString();
		}
		DirectoryDialog dialog = new DirectoryDialog(treeViewer.getControl().getShell(), SWT.SHEET);
		dialog.setMessage(AntPreferencesMessages.AntClasspathBlock_3);
		dialog.setFilterPath(lastUsedPath);
		String path = dialog.open();
		if (path == null) {
			return;
		}
		antHome = path;
		if (path.length() > 0) {
			File rootDir = new File(path, "lib"); //$NON-NLS-1$
			setAntHome(rootDir);
		} else {
			updateContainer();
		}
		dialogSettings.put(IAntUIConstants.DIALOGSTORE_LASTANTHOME, path);
	}

	private void setAntHome(File rootDir) {
		AntClasspathContentProvider contentProvider = (AntClasspathContentProvider) treeViewer.getContentProvider();
		contentProvider.setRefreshEnabled(false);
		contentProvider.removeAllGlobalAntClasspathEntries();
		String[] names = rootDir.list();
		if (names != null) {
			Arrays.sort(names);
			for (int i = 0; i < names.length; i++) {
				File file = new File(rootDir, names[i]);
				if (file.isFile() && file.getPath().endsWith(".jar")) { //$NON-NLS-1$
					try {
						URL url = new URL(IAntCoreConstants.FILE_PROTOCOL + file.getAbsolutePath());
						contentProvider.add(ClasspathModel.ANT_HOME, url);
					}
					catch (MalformedURLException e) {
						// do nothing
					}
				}
			}
		}

		contentProvider.setRefreshEnabled(true);
		updateContainer();
	}

	public String getAntHome() {
		return antHome;
	}

	public void initializeAntHome(String antHomeString) {
		antHome = antHomeString;
	}

	public void setInput(ClasspathModel model) {
		treeViewer.setInput(model);
		validated = 0;
	}

	public boolean validateAntHome() {
		validated++;
		return validateAntHome(antHome) != null;
	}

	public Image getClasspathImage() {
		return labelProvider.getClasspathImage();
	}

	public boolean validateToolsJAR() {
		validated++;
		boolean check = AntUIPlugin.getDefault().getPreferenceStore().getBoolean(IAntUIPreferenceConstants.ANT_TOOLS_JAR_WARNING);
		if (check && !AntUIPlugin.isMacOS()) {
			Object[] entries = antContentProvider.getModel().getEntries(ClasspathModel.ANT_HOME);
			boolean valid = !JARPresent(entries, TOOLS).isEmpty();
			if (!valid) {
				entries = antContentProvider.getModel().getEntries(ClasspathModel.GLOBAL_USER);
				valid = !JARPresent(entries, TOOLS).isEmpty();
				if (!valid) {
					entries = antContentProvider.getModel().getEntries(ClasspathModel.USER);
					valid = !JARPresent(entries, TOOLS).isEmpty();
					if (!valid) {
						MessageDialogWithToggle dialog = MessageDialogWithToggle.openYesNoQuestion(AntUIPlugin.getActiveWorkbenchWindow().getShell(), AntPreferencesMessages.AntClasspathBlock_31, AntPreferencesMessages.AntClasspathBlock_32, AntPreferencesMessages.AntClasspathBlock_33, false, AntUIPlugin.getDefault().getPreferenceStore(), IAntUIPreferenceConstants.ANT_TOOLS_JAR_WARNING);
						valid = dialog.getReturnCode() == IDialogConstants.YES_ID;
					}
				}
			}
			if (!valid) {
				container.setErrorMessage(AntPreferencesMessages.AntClasspathBlock_34);
				setValidated();
			}
			return valid;
		}
		return true;
	}

	private List<String> JARPresent(Object[] classpathEntries, String[] suffixes) {
		if (classpathEntries == null) {
			return Collections.EMPTY_LIST;
		}
		List<String> found = new ArrayList<>(2);
		for (int i = 0; i < classpathEntries.length; i++) {
			String file;
			Object entry = classpathEntries[i];
			if (entry instanceof URL) {
				file = ((URL) entry).getFile();
			} else {
				file = entry.toString();
			}
			for (int j = 0; j < suffixes.length; j++) {
				String suffix = suffixes[j];
				if (file.endsWith(suffix)) {
					found.add(suffix);
				}
			}
		}
		return found;
	}

	public boolean isValidated() {
		return validated >= 2;
	}

	public void setValidated() {
		validated = 2;
	}

	private void addVariable() {
		VariableInputDialog inputDialog = new VariableInputDialog(treeViewer.getControl().getShell());
		inputDialog.open();
		String variableString = inputDialog.getVariableString();
		if (variableString != null && variableString.trim().length() > 0) {
			((AntClasspathContentProvider) treeViewer.getContentProvider()).add(currentParent, variableString);
			treeViewer.setSelection(treeViewer.getSelection());
			updateContainer();
		}
	}
}
