/*******************************************************************************
 * Copyright (c) 2000, 2019 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
 *     Mickael Istria (Red Hat Inc.) - [486901] Avoid blocking URL.equals
 *     Alexander Fedorov <alexander.fedorov@arsysop.ru> - Bug 460381
 *******************************************************************************/
package org.eclipse.ui.actions;

import java.net.URL;
import java.util.ArrayList;

import org.eclipse.core.runtime.IProduct;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IWorkbenchCommandConstants;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.WorkbenchException;
import org.eclipse.ui.internal.ProductProperties;
import org.eclipse.ui.internal.ide.AboutInfo;
import org.eclipse.ui.internal.ide.FeatureSelectionDialog;
import org.eclipse.ui.internal.ide.IDEWorkbenchMessages;
import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
import org.eclipse.ui.internal.ide.IIDEHelpContextIds;
import org.eclipse.ui.internal.ide.dialogs.WelcomeEditorInput;

/**
 * The quick start (Welcome...) action.
 *
 * @deprecated the IDE now uses the new intro mechanism
 */
@Deprecated
public class QuickStartAction extends Action implements
		ActionFactory.IWorkbenchAction {

	private static final String EDITOR_ID = "org.eclipse.ui.internal.ide.dialogs.WelcomeEditor"; //$NON-NLS-1$

	/**
	 * The workbench window; or <code>null</code> if this
	 * action has been <code>dispose</code>d.
	 */
	private IWorkbenchWindow workbenchWindow;

	/**
	 * Create an instance of this class.
	 * <p>
	 * This constructor added to support calling the action from the welcome
	 * page.
	 * </p>
	 */
	public QuickStartAction() {
		this(PlatformUI.getWorkbench().getActiveWorkbenchWindow());
	}

	/**
	 * Creates an instance of this action, for use in the given window.
	 * @param window the window
	 */
	public QuickStartAction(IWorkbenchWindow window) {
		super(IDEWorkbenchMessages.QuickStart_text);
		if (window == null) {
			throw new IllegalArgumentException();
		}
		this.workbenchWindow = window;
		setToolTipText(IDEWorkbenchMessages.QuickStart_toolTip);
		PlatformUI.getWorkbench().getHelpSystem().setHelp(this,
				IIDEHelpContextIds.QUICK_START_ACTION);
		setActionDefinitionId(IWorkbenchCommandConstants.HELP_WELCOME);
	}

	/**
	 * The user has invoked this action.  Prompts for a feature with a welcome page,
	 * then opens the corresponding welcome page.
	 */
	@Override
	public void run() {
		if (workbenchWindow == null) {
			// action has been disposed
			return;
		}
		AboutInfo feature = promptForFeature();
		if (feature != null) {
			openWelcomePage(feature);
		}
	}

	/**
	 * Prompts the user for a feature that has a welcome page.
	 *
	 * @return the chosen feature, or <code>null</code> if none was chosen
	 */
	private AboutInfo promptForFeature() {
		// Ask the user to select a feature
		ArrayList<AboutInfo> welcomeFeatures = new ArrayList<>();

		URL productUrl = null;
		IProduct product = Platform.getProduct();
		if (product != null) {
			productUrl = ProductProperties.getWelcomePageUrl(product);
			welcomeFeatures.add(new AboutInfo(product));
		}

		AboutInfo[] features = IDEWorkbenchPlugin.getDefault()
				.getFeatureInfos();
		for (AboutInfo feature : features) {
			URL url = feature.getWelcomePageURL();
			if (url != null && (productUrl == null || !url.toString().equals(productUrl.toString()))) {
				welcomeFeatures.add(feature);
			}
		}

		Shell shell = workbenchWindow.getShell();

		if (welcomeFeatures.isEmpty()) {
			MessageDialog.openInformation(shell, IDEWorkbenchMessages.QuickStartMessageDialog_title,
					IDEWorkbenchMessages.QuickStartMessageDialog_message);
			return null;
		}

		features = new AboutInfo[welcomeFeatures.size()];
		welcomeFeatures.toArray(features);

		FeatureSelectionDialog d = new FeatureSelectionDialog(shell, features,
				product == null ? null : product.getId(), IDEWorkbenchMessages.WelcomePageSelectionDialog_title,
				IDEWorkbenchMessages.WelcomePageSelectionDialog_message,
				IIDEHelpContextIds.WELCOME_PAGE_SELECTION_DIALOG);
		if (d.open() != Window.OK || d.getResult().size() != 1) {
			return null;
		}
		return d.getFirstResult().orElse(null);
	}

	/**
	 * Opens the welcome page for the given feature.
	 *
	 * @param featureId the about info for the feature
	 * @return <code>true</code> if successful, <code>false</code> otherwise
	 * @throws WorkbenchException if operation failed
	 */
	public boolean openWelcomePage(String featureId) throws WorkbenchException {
		AboutInfo feature = findFeature(featureId);
		if (feature == null || feature.getWelcomePageURL() == null) {
			return false;
		}
		return openWelcomePage(feature);
	}

	/**
	 * Returns the about info for the feature with the given id, or <code>null</code>
	 * if there is no such feature.
	 *
	 * @return the about info for the feature with the given id, or <code>null</code>
	 *   if there is no such feature.
	 */
	private AboutInfo findFeature(String featureId) {
		AboutInfo[] features = IDEWorkbenchPlugin.getDefault()
				.getFeatureInfos();
		for (AboutInfo info : features) {
			if (info.getFeatureId().equals(featureId)) {
				return info;
			}
		}
		return null;
	}

	/**
	 * Opens the welcome page for a feature.
	 *
	 * @param feature the about info for the feature
	 * @return <code>true</code> if successful, <code>false</code> otherwise
	 */
	private boolean openWelcomePage(AboutInfo feature) {
		IWorkbenchPage page = null;

		// See if the feature wants a specific perspective
		String perspectiveId = feature.getWelcomePerspectiveId();

		if (perspectiveId == null) {
			// Just use the current perspective unless one is not open
			// in which case use the default
			page = workbenchWindow.getActivePage();

			if (page == null || page.getPerspective() == null) {
				perspectiveId = PlatformUI.getWorkbench()
						.getPerspectiveRegistry().getDefaultPerspective();
			}
		}

		if (perspectiveId != null) {
			try {
				page = PlatformUI.getWorkbench().showPerspective(perspectiveId,
						workbenchWindow);
			} catch (WorkbenchException e) {
				IDEWorkbenchPlugin
						.log("Error opening perspective: " + perspectiveId, e.getStatus()); //$NON-NLS-1$
				return false;
			}
		}

		if (page == null) {
			return false;
		}

		page.setEditorAreaVisible(true);

		// create input
		WelcomeEditorInput input = new WelcomeEditorInput(feature);

		// see if we already have a welcome editorz
		IEditorPart editor = page.findEditor(input);
		if (editor != null) {
			page.activate(editor);
			return true;
		}

		try {
			page.openEditor(input, EDITOR_ID);
		} catch (PartInitException e) {
			IDEWorkbenchPlugin
					.log("Error opening welcome editor for feature: " + feature.getFeatureId(), e); //$NON-NLS-1$
			IStatus status = new Status(
					IStatus.ERROR,
					IDEWorkbenchPlugin.IDE_WORKBENCH,
					1,
					IDEWorkbenchMessages.QuickStartAction_openEditorException, e);
			ErrorDialog
					.openError(
							workbenchWindow.getShell(),
							IDEWorkbenchMessages.Workbench_openEditorErrorDialogTitle,
							IDEWorkbenchMessages.Workbench_openEditorErrorDialogMessage,
							status);
			return false;
		}
		return true;
	}

	@Override
	public void dispose() {
		if (workbenchWindow == null) {
			// action has already been disposed
			return;
		}
		workbenchWindow = null;
	}

}
