/*******************************************************************************
 * Copyright (c) 2007, 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
 *     Lars Vogel <Lars.Vogel@vogella.com> - Bug 490755
 *     Lucas Bullen <lbullen@redhat.com> & Ian Pun <ipun@redhat.com> - Bug 518652
 *     Axel Richard (Obeo) - Bug 41353 - Launch configurations prototypes
 *******************************************************************************/
package org.eclipse.debug.internal.ui.importexport.launchconfigurations;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.filesystem.IFileStore;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationType;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.internal.core.IInternalDebugCoreConstants;
import org.eclipse.debug.internal.core.LaunchConfiguration;
import org.eclipse.debug.internal.ui.DebugUIPlugin;
import org.eclipse.debug.internal.ui.IDebugHelpContextIds;
import org.eclipse.debug.internal.ui.IInternalDebugUIConstants;
import org.eclipse.debug.internal.ui.SWTFactory;
import org.eclipse.debug.internal.ui.launchConfigurations.LaunchCategoryFilter;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.CheckboxTreeViewer;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.DirectoryDialog;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.model.WorkbenchViewerComparator;
import org.eclipse.ui.progress.UIJob;

import com.ibm.icu.text.MessageFormat;

/**
 * This calls provides the one and only wizard page to the
 * export launch configurations wizard.
 * @since 3.4.0
 */
public class ExportLaunchConfigurationsWizardPage extends WizardPage {

	private ILaunchManager lm = DebugPlugin.getDefault().getLaunchManager();

	/**
	 * The content provider for the tree viewer
	 * @since 3.4.0
	 */
	class ConfigContentProvider implements ITreeContentProvider {

		@Override
		public Object[] getChildren(Object parentElement) {
			if(parentElement instanceof ILaunchConfigurationType) {
				try {
					return getConfigurationTypeChildren((ILaunchConfigurationType) parentElement);
				}
				catch (Exception e) {
					DebugUIPlugin.logErrorMessage(e.getMessage());
				}
			}
			return null;
		}

		@Override
		public Object getParent(Object element) {
			if(element instanceof ILaunchConfiguration) {
				try {
					return ((ILaunchConfiguration)element).getType();
				} catch (CoreException e) {
					return null;
				}
			}
			return null;
		}
		@Override
		public boolean hasChildren(Object element) {
			return element instanceof ILaunchConfigurationType;
		}
		@Override
		public Object[] getElements(Object inputElement) {
			return getUsedLaunchConfigurationTypes();
		}
	}
	private String OVERWRITE = "overwrite"; //$NON-NLS-1$
	private String OLD_PATH = "oldpath"; //$NON-NLS-1$
	private CheckboxTreeViewer fViewer = null;
	private Text fFilePath = null;
	private Button fOverwrite = null;
	private ConfigContentProvider fContentProvider = null;
	private IStructuredSelection selectedElements;
	/**
	 * Constructor
	 */
	protected ExportLaunchConfigurationsWizardPage() {
		super(WizardMessages.ExportLaunchConfigurationsWizard_0);
		setTitle(WizardMessages.ExportLaunchConfigurationsWizard_0);
	}

	protected ExportLaunchConfigurationsWizardPage(IStructuredSelection selection) {
		this();
		selectedElements = selection;
	}

	@Override
	public void createControl(Composite parent) {
		Composite comp = SWTFactory.createComposite(parent, 2, 1, GridData.FILL_BOTH);
		//add the check table
		createViewer(comp);
		//add the file path and browse button
		createFilePath(comp);
		//add the overwrite option
		fOverwrite = SWTFactory.createCheckButton(comp, WizardMessages.ExportLaunchConfigurationsWizardPage_1, null, getDialogSettings().getBoolean(OVERWRITE), 2);
		setControl(comp);
		PlatformUI .getWorkbench().getHelpSystem().setHelp(comp, IDebugHelpContextIds.EXPORT_LAUNCH_CONFIGURATIONS_PAGE);
		setMessage(WizardMessages.ExportLaunchConfigurationsWizardPage_7);
		setPageComplete(isComplete());
	}

	/**
	 * Creates the check table viewer portion of the control
	 * @param parent the parent to add the check table viewer to
	 */
	protected void createViewer(Composite parent) {
		SWTFactory.createWrapLabel(parent, WizardMessages.ExportLaunchConfigurationsWizardPage_3, 2);
		Tree tree = new Tree(parent, SWT.BORDER | SWT.SINGLE | SWT.CHECK);
		GridData gd = new GridData(GridData.FILL_BOTH);
		gd.horizontalSpan = 2;
		tree.setLayoutData(gd);
		fViewer = new CheckboxTreeViewer(tree);
		fViewer.setLabelProvider(DebugUITools.newDebugModelPresentation());
		fViewer.setComparator(new WorkbenchViewerComparator());
		fContentProvider = new ConfigContentProvider();
		fViewer.setContentProvider(fContentProvider);
		fViewer.setInput(getUsedLaunchConfigurationTypes());
		//we don't want to see builders....
		fViewer.addFilter(new LaunchCategoryFilter(IInternalDebugUIConstants.ID_EXTERNAL_TOOL_BUILDER_LAUNCH_CATEGORY));
		//need to force load the children so that select all works initially
		fViewer.expandAll();
		fViewer.collapseAll();
		if (selectedElements != null) {
			Object[] checkedElements = selectedElements.toArray();
			fViewer.setCheckedElements(checkedElements);
			fViewer.setExpandedElements(checkedElements);
			for (Object element : checkedElements) {
				updateCheckedState(element);
			}
		}
		fViewer.addCheckStateListener(event -> {
			updateCheckedState(event.getElement());
			setPageComplete(isComplete());
		});
		Composite buttoncomp = SWTFactory.createComposite(parent, parent.getFont(), 2, 2, GridData.FILL_HORIZONTAL, 0, 0);
		Button button = SWTFactory.createPushButton(buttoncomp, WizardMessages.ExportLaunchConfigurationsWizardPage_8, null);
		button.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				Object[] items = fContentProvider.getElements(fViewer.getInput());
				for (Object item : items) {
					fViewer.setSubtreeChecked(item, true);
				}
				setPageComplete(isComplete());
			}
		});
		button = SWTFactory.createPushButton(buttoncomp, WizardMessages.ExportLaunchConfigurationsWizardPage_9, null);
		button.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				Object[] items = fContentProvider.getElements(fViewer.getInput());
				for (Object item : items) {
					fViewer.setSubtreeChecked(item, false);
				}
				setPageComplete(isComplete());
			}
		});
	}

	/**
	 * @return launch configuration types which currently have configuration or
	 *         prototype children, and are therefore relevant for exporting
	 */
	private ILaunchConfigurationType[] getUsedLaunchConfigurationTypes() {
		return Arrays.stream(DebugPlugin.getDefault().getLaunchManager().getLaunchConfigurationTypes()).filter(launchConfigType -> {
			try {
				return getConfigurationTypeChildren(launchConfigType).length > 0;
			} catch (CoreException e) {
				DebugUIPlugin.logErrorMessage(e.getMessage());
			}
			return true;
		}).toArray(ILaunchConfigurationType[]::new);
	}

	private ILaunchConfiguration[] getConfigurationTypeChildren(ILaunchConfigurationType launchConfigurationTypeParent) throws CoreException {
		return lm.getLaunchConfigurations(launchConfigurationTypeParent, ILaunchConfiguration.CONFIGURATION | ILaunchConfiguration.PROTOTYPE);
	}

	/**
	 * Updates the checked state of child launch configurations if the parent type is checked
	 * @param item
	 */
	protected void updateCheckedState(Object element) {
		boolean state = fViewer.getChecked(element);
		if(element instanceof ILaunchConfigurationType) {
			Object[] items = ((ConfigContentProvider)fViewer.getContentProvider()).getChildren(element);
			for (Object item : items) {
				fViewer.setChecked(item, state);
			}
			fViewer.setGrayed(element, false);
		}
		else if(element instanceof ILaunchConfiguration) {
			ConfigContentProvider ccp = (ConfigContentProvider) fViewer.getContentProvider();
			Object parent = ccp.getParent(element);
			Object[] items = ccp.getChildren(parent);
			boolean checked = true;
			boolean onechecked = false;
			for (Object item : items) {
				state = fViewer.getChecked(item);
				checked &= state;
				if(state) {
					onechecked = true;
				}
			}
			fViewer.setGrayed(parent, onechecked & !checked);
			fViewer.setChecked(parent, checked | onechecked);
		}
	}

	/**
	 * Creates the controls for the file path selection area of the page
	 * @param parent
	 */
	protected void createFilePath(Composite parent) {
		Composite comp = SWTFactory.createComposite(parent, parent.getFont(), 3, 2, GridData.FILL_HORIZONTAL, 0, 10);
		SWTFactory.createLabel(comp, WizardMessages.ExportLaunchConfigurationsWizardPage_4, 1);
		fFilePath = SWTFactory.createText(comp, SWT.SINGLE | SWT.BORDER, 1);
		String opath = getDialogSettings().get(OLD_PATH);
		fFilePath.setText((opath == null ? IInternalDebugCoreConstants.EMPTY_STRING : opath));
		fFilePath.addModifyListener(e -> setPageComplete(isComplete()));
		Button button = SWTFactory.createPushButton(comp, WizardMessages.ExportLaunchConfigurationsWizardPage_0, null, GridData.END);
		button.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				DirectoryDialog dd = new DirectoryDialog(getContainer().getShell(), SWT.SHEET);
				dd.setText(WizardMessages.ExportLaunchConfigurationsWizard_0);
				String file = dd.open();
				if(file != null) {
					IPath path = new Path(file);
					if (path != null) {
						fFilePath.setText(path.toString());
						setPageComplete(isComplete());
					}
				}
			}
		});
	}

	/**
	 * Returns if the page is complete
	 * @return true if the page is complete and can be 'finished', false otherwise
	 */
	protected boolean isComplete() {
		Object[] elements = fViewer.getCheckedElements();
		boolean oneconfig = false;
		for (Object element : elements) {
			if (element instanceof ILaunchConfiguration) {
				oneconfig = true;
				break;
			}
		}
		if(elements.length < 1 || !oneconfig) {
			setErrorMessage(WizardMessages.ExportLaunchConfigurationsWizardPage_5);
			return false;
		}
		String path = fFilePath.getText().trim();
		if(path.equals(IInternalDebugCoreConstants.EMPTY_STRING)) {
			setErrorMessage(WizardMessages.ExportLaunchConfigurationsWizardPage_6);
			return false;
		}
		if ((new File(path)).isFile()) {
			setErrorMessage(WizardMessages.ExportLaunchConfigurationsWizardPage_2);
			return false;
		}
		setErrorMessage(null);
		setMessage(WizardMessages.ExportLaunchConfigurationsWizardPage_7);
		return true;
	}

	@Override
	public Image getImage() {
		return DebugUITools.getImage(IInternalDebugUIConstants.IMG_WIZBAN_EXPORT_CONFIGS);
	}

	/**
	 * This method performs the work of the page
	 * @return if the export job was successful or not
	 */
	public boolean finish() {
		final String dpath = fFilePath.getText().trim();
		IDialogSettings settings = getDialogSettings();
		settings.put(OVERWRITE, fOverwrite.getSelection());
		settings.put(OLD_PATH, dpath);
		final Object[] configs = fViewer.getCheckedElements();
		final boolean overwrite = fOverwrite.getSelection();
		UIJob exportjob = new UIJob(getContainer().getShell().getDisplay(), WizardMessages.ExportLaunchConfigurationsWizard_0) {
			@Override
			public IStatus runInUIThread(IProgressMonitor monitor) {
				IProgressMonitor progressMonitor = monitor != null ? monitor : new NullProgressMonitor();
				IPath destpath = new Path(dpath);
				File destfolder = destpath.toFile();
				if(!destfolder.exists()) {
					destfolder.mkdirs();
				}
				progressMonitor.beginTask(WizardMessages.ExportLaunchConfigurationsWizardPage_10, configs.length);
				try {
					List<IStatus> errors = null;
					IFileStore file = null;
					File newfile = null;
					boolean owall = false, nowall = false;
					MessageDialog dialog = null;
					for (Object config : configs) {
						if (progressMonitor.isCanceled()) {
							return Status.CANCEL_STATUS;
						}
						if (config instanceof ILaunchConfiguration) {
							try {
								LaunchConfiguration launchConfig = (LaunchConfiguration) config;
								file = launchConfig.getFileStore();
								if (file == null) {
									if (errors == null) {
										errors = new ArrayList<>(configs.length);
									}
									errors.add(new Status(IStatus.ERROR, DebugUIPlugin.getUniqueIdentifier(), MessageFormat.format(WizardMessages.ExportLaunchConfigurationsWizardPage_19, new Object[] { launchConfig.getName() }), null));
								} else {
									newfile = new File(destpath.append(file.getName()).toOSString());
									if(newfile.exists() & !overwrite) {
										if(nowall) {
											continue;
										}
										dialog = new MessageDialog(DebugUIPlugin.getShell(), WizardMessages.ExportLaunchConfigurationsWizardPage_11, null, MessageFormat.format(WizardMessages.ExportLaunchConfigurationsWizardPage_12, new Object[] { file.getName() }), MessageDialog.QUESTION, new String[] {
											WizardMessages.ExportLaunchConfigurationsWizardPage_13,
											WizardMessages.ExportLaunchConfigurationsWizardPage_14,
											WizardMessages.ExportLaunchConfigurationsWizardPage_15,
											WizardMessages.ExportLaunchConfigurationsWizardPage_16,
											WizardMessages.ExportLaunchConfigurationsWizardPage_17 }, 0);
										if(!owall) {
											int ret = dialog.open();
											switch(ret) {
												case 0: {
													copyFile(file, newfile);
													break;
												}
												case 1: {
													owall = true;
													copyFile(file, newfile);
													break;
												}
												case 3: {
													nowall = true;
													break;
												}
												case 4: {
													progressMonitor.setCanceled(true);
													break;
												}
												default:
													break;
											}
										}
										else if(!nowall) {
											copyFile(file, newfile);
										}
									}
									else {
										copyFile(file, newfile);
									}
								}
							} catch (IOException e) {
								if (errors == null) {
									errors = new ArrayList<>(configs.length);
								}
								errors.add(new Status(IStatus.ERROR, DebugUIPlugin.getUniqueIdentifier(),
										e.getMessage(), e));
							} catch (CoreException e) {
								if (errors == null) {
									errors = new ArrayList<>(configs.length);
								}
								errors.add(e.getStatus());
							}
						}
						if (!progressMonitor.isCanceled()) {
							progressMonitor.worked(1);
						}
					}
					if (errors == null || errors.isEmpty()) {
						return Status.OK_STATUS;
					} else {
						if (errors.size() == 1) {
							return errors.get(0);
						} else {
							return new MultiStatus(DebugUIPlugin.getUniqueIdentifier(), 0,
									errors.toArray(new IStatus[errors.size()]),
									WizardMessages.ExportLaunchConfigurationsWizardPage_18, null);
						}
					}
				}
				finally {
					progressMonitor.done();
				}
			}
		};
		exportjob.schedule();
		return true;
	}

	/**
	 * Copies a file from one location to another
	 * @param in the file to copy
	 * @param out the file to be copied out to
	 * @throws Exception
	 * @since 3.5
	 */
	protected void copyFile(IFileStore in, File out) throws CoreException, IOException {
		try (BufferedInputStream is = new BufferedInputStream(in.openInputStream(EFS.NONE, null)); BufferedOutputStream os = new BufferedOutputStream(new FileOutputStream(out))) {
			byte[] buf = new byte[1024];
			int i = 0;
			while ((i = is.read(buf)) != -1) {
				os.write(buf, 0, i);
			}
		}
	}
}
