/*******************************************************************************
 * Copyright (c) 2005, 2022 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
 *     EclipseSource Corporation - ongoing enhancements
 *******************************************************************************/
package org.eclipse.pde.internal.ui.launcher;

import static org.eclipse.pde.internal.launching.launcher.BundleLauncherHelper.formatAdditionalPluginEntry;
import static org.eclipse.pde.internal.launching.launcher.BundleLauncherHelper.formatFeatureEntry;

import java.io.File;
import java.util.*;
import java.util.stream.Collectors;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.*;
import org.eclipse.debug.core.*;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.debug.ui.IDebugModelPresentation;
import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.window.Window;
import org.eclipse.pde.core.plugin.*;
import org.eclipse.pde.internal.core.*;
import org.eclipse.pde.internal.core.ifeature.*;
import org.eclipse.pde.internal.core.iproduct.*;
import org.eclipse.pde.internal.core.iproduct.IProduct;
import org.eclipse.pde.internal.core.util.CoreUtility;
import org.eclipse.pde.internal.launching.IPDEConstants;
import org.eclipse.pde.internal.launching.launcher.BundleLauncherHelper;
import org.eclipse.pde.internal.launching.launcher.BundleLauncherHelper.AdditionalPluginData;
import org.eclipse.pde.internal.launching.launcher.LaunchArgumentsHelper;
import org.eclipse.pde.internal.ui.PDEPlugin;
import org.eclipse.pde.internal.ui.PDEUIMessages;
import org.eclipse.pde.launching.IPDELauncherConstants;
import org.eclipse.pde.launching.PDESourcePathProvider;
import org.eclipse.pde.ui.launcher.EclipseLaunchShortcut;
import org.eclipse.ui.dialogs.ElementListSelectionDialog;

public class LaunchAction extends Action {

	private IProduct fProduct;
	private String fMode;
	private String fPath;
	private Map<String, IPluginConfiguration> fPluginConfigurations;

	public LaunchAction(IProduct product, String path, String mode) {
		fProduct = product;
		fMode = mode;
		fPath = path;
		// initialize configurations... we should do this lazily
		// TODO
		fPluginConfigurations = new HashMap<>();
		IPluginConfiguration[] configurations = fProduct.getPluginConfigurations();
		for (IPluginConfiguration config : configurations) {
			fPluginConfigurations.put(config.getId(), config);
		}
	}

	@Override
	public void run() {
		try {
			ILaunchConfiguration config = findLaunchConfiguration();
			if (config != null)
				DebugUITools.launch(config, fMode);
		} catch (CoreException e) {
		}
	}

	private ILaunchConfiguration findLaunchConfiguration() throws CoreException {
		ILaunchConfiguration[] configs = getLaunchConfigurations();

		if (configs.length == 0)
			return createConfiguration();

		ILaunchConfiguration config = null;
		if (configs.length == 1) {
			config = configs[0];
		} else {
			// Prompt the user to choose a config.
			config = chooseConfiguration(configs);
		}

		if (config != null) {
			config = refreshConfiguration(config.getWorkingCopy());
		}
		return config;
	}

	private ILaunchConfiguration refreshConfiguration(ILaunchConfigurationWorkingCopy wc) throws CoreException {
		wc.setAttribute(IPDELauncherConstants.PRODUCT, fProduct.getProductId());
		wc.setAttribute(IPDELauncherConstants.APPLICATION, fProduct.getApplication());

		if (TargetPlatformHelper.usesNewApplicationModel())
			wc.setAttribute(IPDEConstants.LAUNCHER_PDE_VERSION, "3.3"); //$NON-NLS-1$
		else if (TargetPlatformHelper.getTargetVersion() >= 3.2)
			wc.setAttribute(IPDEConstants.LAUNCHER_PDE_VERSION, "3.2a"); //$NON-NLS-1$

		String os = Platform.getOS();
		String arch = Platform.getOSArch();
		wc.setAttribute(IJavaLaunchConfigurationConstants.ATTR_VM_ARGUMENTS, getVMArguments(os, arch));
		wc.setAttribute(IJavaLaunchConfigurationConstants.ATTR_PROGRAM_ARGUMENTS, getProgramArguments(os, arch));
		wc.setAttribute(IJavaLaunchConfigurationConstants.ATTR_JRE_CONTAINER_PATH, getJREContainer(os));
		Set<String> wsplugins = new HashSet<>();
		Set<String> explugins = new HashSet<>();
		IPluginModelBase[] models = getModels();
		for (IPluginModelBase model : models) {
			if (model.getUnderlyingResource() == null) {
				appendBundle(explugins, model);
			} else {
				appendBundle(wsplugins, model);
			}
		}
		wc.setAttribute(IPDELauncherConstants.SELECTED_WORKSPACE_BUNDLES, wsplugins);
		wc.setAttribute(IPDELauncherConstants.SELECTED_TARGET_BUNDLES, explugins);
		String configIni = getTemplateConfigIni(os);
		wc.setAttribute(IPDELauncherConstants.CONFIG_GENERATE_DEFAULT, configIni == null);
		if (configIni != null)
			wc.setAttribute(IPDELauncherConstants.CONFIG_TEMPLATE_LOCATION, configIni);

		if (fProduct.useFeatures()) {
			refreshFeatureLaunchAttributes(wc, models);
		}

		return wc.doSave();
	}

	private void refreshFeatureLaunchAttributes(ILaunchConfigurationWorkingCopy wc, IPluginModelBase[] models) {
		FeatureModelManager fmm = PDECore.getDefault().getFeatureModelManager();
		Set<String> selectedFeatures = Arrays.stream(fProduct.getFeatures()) //
				.map(f -> fmm.findFeatureModel(f.getId(), f.getVersion())).filter(Objects::nonNull)
				.map(m -> formatFeatureEntry(m.getFeature().getId(), IPDELauncherConstants.LOCATION_DEFAULT))
				.collect(Collectors.toCollection(LinkedHashSet::new));

		Set<String> additionalPlugins = Arrays.stream(models)
				.map(model -> getPluginConfiguration(model)
						.map(c -> formatAdditionalPluginEntry(model, c.fResolution, true, c.fStartLevel, c.fAutoStart))
						.orElse(null))
				.filter(Objects::nonNull).collect(Collectors.toCollection(LinkedHashSet::new));

		wc.setAttribute(IPDELauncherConstants.SELECTED_FEATURES, selectedFeatures);
		wc.setAttribute(IPDELauncherConstants.ADDITIONAL_PLUGINS, additionalPlugins);
		wc.setAttribute(IPDELauncherConstants.USE_CUSTOM_FEATURES, true);
	}

	private void appendBundle(Set<String> plugins, IPluginModelBase model) {
		AdditionalPluginData config = getPluginConfiguration(model).orElse(FeatureBlock.DEFAULT_PLUGIN_DATA);
		String entry = BundleLauncherHelper.formatBundleEntry(model, config.fStartLevel, config.fAutoStart);
		plugins.add(entry);
	}

	private Optional<AdditionalPluginData> getPluginConfiguration(IPluginModelBase model) {
		IPluginConfiguration configuration = fPluginConfigurations.get(model.getPluginBase().getId());
		if (configuration == null) {
			return Optional.empty();
		}

		String startLevel = (configuration.getStartLevel() > 0) ? String.valueOf(configuration.getStartLevel())
				: "default"; //$NON-NLS-1$
		String autoStart = String.valueOf(configuration.isAutoStart());
		AdditionalPluginData data = new AdditionalPluginData(IPDELauncherConstants.LOCATION_DEFAULT, true, startLevel,
				autoStart);
		return Optional.of(data);
	}

	private String getProgramArguments(String os, String arch) {
		StringBuilder buffer = new StringBuilder(LaunchArgumentsHelper.getInitialProgramArguments());
		IArgumentsInfo info = fProduct.getLauncherArguments();
		String userArgs = (info != null) ? CoreUtility.normalize(info.getCompleteProgramArguments(os, arch)) : ""; //$NON-NLS-1$
		return concatArgs(buffer, userArgs);
	}

	private String getVMArguments(String os, String arch) {
		StringBuilder buffer = new StringBuilder(LaunchArgumentsHelper.getInitialVMArguments());
		IArgumentsInfo info = fProduct.getLauncherArguments();
		String userArgs = (info != null) ? CoreUtility.normalize(info.getCompleteVMArguments(os, arch)) : ""; //$NON-NLS-1$
		return concatArgs(buffer, userArgs);
	}

	private String concatArgs(StringBuilder initialArgs, String userArgs) {
		List<String> initialArgsList = Arrays.asList(DebugPlugin.splitArguments(initialArgs.toString()));
		if (userArgs != null && userArgs.length() > 0) {
			List<String> userArgsList = Arrays.asList(DebugPlugin.splitArguments(userArgs));
			boolean previousHasSubArgument = false;
			for (String userArg : userArgsList) {
				boolean hasSubArgument = userArg.toString().equals('-' + IEnvironment.P_OS) || userArg.toString().equals('-' + IEnvironment.P_WS);
				hasSubArgument = hasSubArgument || userArg.toString().equals('-' + IEnvironment.P_ARCH) || userArg.toString().equals('-' + IEnvironment.P_NL);
				if (!initialArgsList.contains(userArg) || hasSubArgument || previousHasSubArgument) {
					initialArgs.append(' ');
					initialArgs.append(userArg);
				}
				previousHasSubArgument = hasSubArgument;
			}
		}
		String arguments = null;
		try {
			arguments = removeDuplicateArguments(initialArgs);
		} catch (Exception e) {
			PDEPlugin.log(e);
			return initialArgs.toString();
		}
		return arguments;
	}

	private String removeDuplicateArguments(StringBuilder initialArgs) {
		String[] progArguments = { '-' + IEnvironment.P_OS, '-' + IEnvironment.P_WS, '-' + IEnvironment.P_ARCH,
				'-' + IEnvironment.P_NL };
		String defaultStart = "${target."; //$NON-NLS-1$ // see
											// LaunchArgumentHelper
		ArrayList<String> userArgsList = new ArrayList<>(
				Arrays.asList(DebugPlugin.splitArguments(initialArgs.toString())));
		for (String progArgument : progArguments) {
			int index1 = userArgsList.indexOf(progArgument);
			int index2 = userArgsList.lastIndexOf(progArgument);
			if (index1 != index2) {
				String s1 = userArgsList.get(index1 + 1);
				String s2 = userArgsList.get(index2 + 1);
				// in case of duplicate remove initial program arguments
				if (s1.startsWith(defaultStart) && !s2.startsWith(defaultStart)) {
					userArgsList.remove(index1);
					userArgsList.remove(index1);
				} else if (s2.startsWith(defaultStart) && !s1.startsWith(defaultStart)) {
					userArgsList.remove(index2);
					userArgsList.remove(index2);
				}
			}
		}
		StringBuilder arguments = new StringBuilder();
		for (Iterator<String> iterator = userArgsList.iterator(); iterator.hasNext();) {
			Object userArg = iterator.next();
			arguments.append(userArg);
			if(iterator.hasNext())
				arguments.append(' ');
		}
		return arguments.toString();
	}

	private String getJREContainer(String os) {
		IJREInfo info = fProduct.getJREInfo();
		if (info != null) {
			IPath jrePath = info.getJREContainerPath(os);
			if (jrePath != null) {
				return jrePath.toPortableString();
			}
		}
		return null;
	}

	private IPluginModelBase[] getModels() {
		Set<IPluginModelBase> launchPlugins = new HashSet<>();
		if (fProduct.useFeatures()) {
			IFeatureModel[] features = getUniqueFeatures();
			for (IFeatureModel feature : features) {
				addFeaturePlugins(feature.getFeature(), launchPlugins);
			}
		} else {
			IProductPlugin[] plugins = fProduct.getPlugins();
			for (IProductPlugin plugin : plugins) {
				String id = plugin.getId();
				if (id == null)
					continue;
				IPluginModelBase model = PluginRegistry.findModel(id);
				if (model != null && TargetPlatformHelper.matchesCurrentEnvironment(model))
					launchPlugins.add(model);
			}
		}
		return launchPlugins.toArray(new IPluginModelBase[launchPlugins.size()]);
	}

	private IFeatureModel[] getUniqueFeatures() {
		ArrayList<IFeatureModel> list = new ArrayList<>();
		IProductFeature[] features = fProduct.getFeatures();
		for (IProductFeature feature : features) {
			String id = feature.getId();
			String version = feature.getVersion();
			addFeatureAndChildren(id, version, list);
		}
		return list.toArray(new IFeatureModel[list.size()]);
	}

	private void addFeatureAndChildren(String id, String version, List<IFeatureModel> list) {
		FeatureModelManager manager = PDECore.getDefault().getFeatureModelManager();
		IFeatureModel model = manager.findFeatureModel(id, version);
		if (model == null || list.contains(model))
			return;

		list.add(model);

		IFeatureChild[] children = model.getFeature().getIncludedFeatures();
		for (IFeatureChild element : children) {
			addFeatureAndChildren(element.getId(), element.getVersion(), list);
		}
	}

	private void addFeaturePlugins(IFeature feature, Set<IPluginModelBase> launchPlugins) {
		IFeaturePlugin[] plugins = feature.getPlugins();
		for (IFeaturePlugin plugin : plugins) {
			String id = plugin.getId();
			String version = plugin.getVersion();
			if (id == null || version == null)
				continue;
			IPluginModelBase model = PluginRegistry.findModel(id, version, IMatchRules.EQUIVALENT, null);
			if (model == null)
				model = PluginRegistry.findModel(id);
			if (model != null && !launchPlugins.contains(model) && TargetPlatformHelper.matchesCurrentEnvironment(model))
				launchPlugins.add(model);
		}
	}

	private String getTemplateConfigIni(String os) {
		IConfigurationFileInfo info = fProduct.getConfigurationFileInfo();
		if (info != null) {
			String path = info.getPath(os);
			if (path == null) // if we can't find an os path, let's try the normal one
				path = info.getPath(null);
			if (path != null) {
				String expandedPath = getExpandedPath(path);
				if (expandedPath != null) {
					File file = new File(expandedPath);
					if (file.exists() && file.isFile())
						return file.getAbsolutePath();
				}
			}
		}
		return null;
	}

	private String getExpandedPath(String path) {
		if (path == null || path.length() == 0)
			return null;
		IResource resource = PDEPlugin.getWorkspace().getRoot().findMember(new Path(path));
		if (resource != null) {
			IPath fullPath = resource.getLocation();
			return fullPath == null ? null : fullPath.toOSString();
		}
		return null;
	}

	private ILaunchConfiguration chooseConfiguration(ILaunchConfiguration[] configs) {
		IDebugModelPresentation labelProvider = DebugUITools.newDebugModelPresentation();
		ElementListSelectionDialog dialog = new ElementListSelectionDialog(PDEPlugin.getActiveWorkbenchShell(), labelProvider);
		dialog.setElements(configs);
		dialog.setTitle(PDEUIMessages.RuntimeWorkbenchShortcut_title);
		if (fMode.equals(ILaunchManager.DEBUG_MODE)) {
			dialog.setMessage(PDEUIMessages.RuntimeWorkbenchShortcut_select_debug);
		} else {
			dialog.setMessage(PDEUIMessages.RuntimeWorkbenchShortcut_select_run);
		}
		dialog.setMultipleSelection(false);
		int result = dialog.open();
		labelProvider.dispose();
		if (result == Window.OK) {
			return (ILaunchConfiguration) dialog.getFirstResult();
		}
		return null;
	}

	private ILaunchConfiguration createConfiguration() throws CoreException {
		ILaunchConfigurationType configType = getWorkbenchLaunchConfigType();
		String computedName = getComputedName(new Path(fPath).lastSegment());
		ILaunchConfigurationWorkingCopy wc = configType.newInstance(null, computedName);
		wc.setAttribute(IPDELauncherConstants.LOCATION, LaunchArgumentsHelper.getDefaultWorkspaceLocation(computedName));
		wc.setAttribute(IPDELauncherConstants.USE_DEFAULT, false);
		wc.setAttribute(IPDELauncherConstants.DOCLEAR, false);
		wc.setAttribute(IPDEConstants.DOCLEARLOG, false);
		wc.setAttribute(IPDEConstants.APPEND_ARGS_EXPLICITLY, true);
		wc.setAttribute(IPDELauncherConstants.ASKCLEAR, true);
		wc.setAttribute(IPDELauncherConstants.USE_PRODUCT, true);
		wc.setAttribute(IPDELauncherConstants.AUTOMATIC_VALIDATE, true);
		wc.setAttribute(IPDELauncherConstants.AUTOMATIC_ADD, false);
		wc.setAttribute(IPDELauncherConstants.PRODUCT_FILE, fPath);
		wc.setAttribute(IJavaLaunchConfigurationConstants.ATTR_SOURCE_PATH_PROVIDER, PDESourcePathProvider.ID);
		return refreshConfiguration(wc);
	}

	private String getComputedName(String prefix) {
		ILaunchManager lm = DebugPlugin.getDefault().getLaunchManager();
		return lm.generateLaunchConfigurationName(prefix);
	}

	private ILaunchConfiguration[] getLaunchConfigurations() throws CoreException {
		ArrayList<ILaunchConfiguration> result = new ArrayList<>();
		ILaunchManager manager = DebugPlugin.getDefault().getLaunchManager();
		ILaunchConfigurationType type = manager.getLaunchConfigurationType(EclipseLaunchShortcut.CONFIGURATION_TYPE);
		ILaunchConfiguration[] configs = manager.getLaunchConfigurations(type);
		for (int i = 0; i < configs.length; i++) {
			if (!DebugUITools.isPrivate(configs[i])) {
				String path = configs[i].getAttribute(IPDELauncherConstants.PRODUCT_FILE, ""); //$NON-NLS-1$
				if (new Path(fPath).equals(new Path(path))) {
					result.add(configs[i]);
				}
			}
		}
		return result.toArray(new ILaunchConfiguration[result.size()]);
	}

	protected ILaunchConfigurationType getWorkbenchLaunchConfigType() {
		ILaunchManager lm = DebugPlugin.getDefault().getLaunchManager();
		return lm.getLaunchConfigurationType(EclipseLaunchShortcut.CONFIGURATION_TYPE);
	}

}
