/*******************************************************************************
 * Copyright (c) 2000, 2009 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
 *     Brock Janiczak <brockj@tpg.com.au> - Bug 161536 Warn user when committing resources with problem markers
 *     Brock Janiczak <brockj@tpg.com.au> - Bug 177519 [Wizards] Adopt new IResource.findMaxProblemSeverity API
 *     Brock Janiczak <brockj@tpg.com.au> - Bug 166333 [Wizards] Show diff in CVS commit dialog
 *     
 *******************************************************************************/
package org.eclipse.team.internal.ccvs.ui.wizards;

import java.lang.reflect.InvocationTargetException;
import java.util.*;

import org.eclipse.core.resources.*;
import org.eclipse.core.resources.mapping.ResourceMapping;
import org.eclipse.core.resources.mapping.ResourceTraversal;
import org.eclipse.core.runtime.*;
import org.eclipse.core.runtime.jobs.*;
import org.eclipse.jface.dialogs.*;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.wizard.IWizardPage;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.team.core.IFileContentManager;
import org.eclipse.team.core.Team;
import org.eclipse.team.core.diff.*;
import org.eclipse.team.core.mapping.*;
import org.eclipse.team.core.synchronize.SyncInfoSet;
import org.eclipse.team.internal.ccvs.core.*;
import org.eclipse.team.internal.ccvs.core.client.Command;
import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot;
import org.eclipse.team.internal.ccvs.ui.*;
import org.eclipse.team.internal.ccvs.ui.actions.CommitAction;
import org.eclipse.team.internal.ccvs.ui.mappings.AbstractCommitAction;
import org.eclipse.team.internal.ccvs.ui.mappings.WorkspaceSubscriberContext;
import org.eclipse.team.internal.ccvs.ui.operations.*;
import org.eclipse.team.internal.core.subscribers.SubscriberDiffTreeEventHandler;
import org.eclipse.team.internal.ui.Policy;
import org.eclipse.team.internal.ui.Utils;
import org.eclipse.team.ui.synchronize.ModelSynchronizeParticipant;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.PlatformUI;

/**
 * A wizard to commit the resources whose synchronization state is given in form
 * of a set of <code>SyncInfo</code>.
 */
public class CommitWizard extends ResizableWizard {
	
	public static final String COMMIT_WIZARD_DIALOG_SETTINGS = "CommitWizard"; //$NON-NLS-1$
	
	/**
	 * An operation to add and commit resources to a CVS repository.
	 */
	public static class AddAndCommitOperation extends CVSOperation {
		
		private final IResource[] fAllResources;
		private final String fComment;
		
		private Map fModesForExtensionsForOneTime;
		private Map fModesForNamesForOneTime;
		
		private IResource[] fNewResources;
		private IJobChangeListener jobListener;
		
		public AddAndCommitOperation(IWorkbenchPart part, IResource[] allResources, IResource[] newResources, String comment) {
			super(part);
			fAllResources = allResources;
			fNewResources = newResources;
			fModesForExtensionsForOneTime = Collections.EMPTY_MAP;
			fModesForNamesForOneTime= Collections.EMPTY_MAP;
			fComment = comment;
		}
		
		public void setModesForExtensionsForOneTime(Map modes) {
			if (modes != null)
				fModesForExtensionsForOneTime= modes;
		}
		
		public void setModesForNamesForOneTime(Map modes) {
			if (modes != null)
				fModesForNamesForOneTime= modes;
		}
		
		@Override
		protected void execute(IProgressMonitor monitor) throws CVSException, InterruptedException {
			try {
				monitor.beginTask(null, (fNewResources.length + fAllResources.length) * 100);
				if (fNewResources.length > 0) {
					final AddOperation op= new AddOperation(getPart(), RepositoryProviderOperation.asResourceMappers(fNewResources));
					op.addModesForExtensions(fModesForExtensionsForOneTime);
					op.addModesForNames(fModesForNamesForOneTime);
					op.run(Policy.subMonitorFor(monitor, fNewResources.length * 100));
				}
				if (fAllResources.length > 0) {
					CommitOperation commitOperation = new CommitOperation(getPart(), RepositoryProviderOperation.asResourceMappers(fAllResources), new Command.LocalOption[0], fComment) {
						@Override
						public boolean consultModelsForMappings() {
							// Do not consult models from the commit wizard
							return false;
						}
					};
					commitOperation.run(Policy.subMonitorFor(monitor, fAllResources.length * 100));
				}
			} catch (InvocationTargetException e) {
				throw CVSException.wrapException(e);
			} finally {
				monitor.done();
			}
		}
		
		@Override
		protected String getJobName() {
			return CVSUIMessages.CommitWizard_0; 
		}
		
		@Override
		protected String getTaskName() {
			return CVSUIMessages.CommitWizard_1; 
		}

		/*
		 * Set the job listener. It will only recieve scheduled and done
		 * events as these are what are used by a sync model operation
		 * to show busy state in the sync view.
		 */
		protected void setJobChangeListener(IJobChangeListener jobListener) {
			this.jobListener = jobListener;
		}
		
		@Override
		public void done(IJobChangeEvent event) {
			super.done(event);
			if (jobListener != null)
				jobListener.done(event);
		}
		
		@Override
		public void scheduled(IJobChangeEvent event) {
			super.scheduled(event);
			if (jobListener != null)
				jobListener.scheduled(event);
		}
	}
	
	private final IResource[] fResources;
	private IResource[] fUnaddedDiffs;
	private final ModelSynchronizeParticipant fParticipant;
	
	private CommitWizardFileTypePage fFileTypePage;
	private CommitWizardCommitPage fCommitPage;
	private IJobChangeListener jobListener;
	private IWorkbenchPart part;
	
	public CommitWizard(SyncInfoSet infos) throws CVSException {
		this(infos.getResources());
	}
	
	public CommitWizard(final IResource [] resources) throws CVSException {
		
		super(COMMIT_WIZARD_DIALOG_SETTINGS, CVSUIPlugin.getPlugin().getDialogSettings());
		
		setNeedsProgressMonitor(true);
		setWindowTitle(CVSUIMessages.CommitWizard_2); 
		setDefaultPageImageDescriptor(CVSUIPlugin.getPlugin().getImageDescriptor(ICVSUIConstants.IMG_WIZBAN_NEW_LOCATION));
		
		fResources= resources;
		ResourceMapping[] mappings = Utils.getResourceMappings(resources);
		fParticipant = createWorkspaceParticipant(mappings, getShell());

		getAllOutOfSync();
		fUnaddedDiffs = getUnaddedResources(getDiffTree().getAffectedResources());
	}

	private ModelSynchronizeParticipant createWorkspaceParticipant(ResourceMapping[] selectedMappings, Shell shell) {
		ISynchronizationScopeManager manager = WorkspaceSubscriberContext.createWorkspaceScopeManager(selectedMappings, true, CommitAction.isIncludeChangeSets(shell, CVSUIMessages.SyncAction_1));
		return new CommitWizardParticipant(WorkspaceSubscriberContext.createContext(manager, ISynchronizationContext.THREE_WAY), this);
	}

	public CommitWizard(SyncInfoSet infos, IJobChangeListener jobListener) throws CVSException {
		this(infos);
		this.jobListener = jobListener;
	}

	private void getAllOutOfSync() throws CVSException {
		try {
			ISynchronizationContext context = getParticipant().getContext();
			SubscriberDiffTreeEventHandler handler = Adapters.adapt(context, SubscriberDiffTreeEventHandler.class);
			handler.initializeIfNeeded();
			Job.getJobManager().join(context, null);
		} catch (InterruptedException e) {
			throw new OperationCanceledException();
		}
	}

	public boolean hasOutgoingChanges() {
		IResourceDiffTree tree = getDiffTree();
		return tree != null && tree.hasMatchingDiffs(ResourcesPlugin.getWorkspace().getRoot().getFullPath(), new FastDiffFilter() {
			@Override
			public boolean select(IDiff diff) {
				return AbstractCommitAction.hasLocalChange(diff);
			}
		});
	}
	
	boolean hasConflicts() {
		IResourceDiffTree tree = getDiffTree();
		return tree != null && tree.hasMatchingDiffs(ResourcesPlugin.getWorkspace().getRoot().getFullPath(), new FastDiffFilter() {
			@Override
			public boolean select(IDiff diff) {
				if (diff instanceof IThreeWayDiff) {
					IThreeWayDiff twd = (IThreeWayDiff) diff;
					return twd.getDirection() == IThreeWayDiff.CONFLICTING;
				}
				return false;
			}
		});
	}
	
	public int getHighestProblemSeverity() {
		IResource[] resources = getDiffTree().getAffectedResources();
		int mostSeriousSeverity = -1;
		
		for (int i = 0; i < resources.length; i++) {
			IResource resource = resources[i];
			try {
				int severity = resource.findMaxProblemSeverity(IMarker.PROBLEM, true, IResource.DEPTH_ZERO);
				if (severity > mostSeriousSeverity) {
					mostSeriousSeverity = severity;
				}
			} catch (CoreException e) {
			}
		}
		
		return mostSeriousSeverity;
	}

	IResourceDiffTree getDiffTree() {
		return fParticipant.getContext().getDiffTree();
	}

	public CommitWizardFileTypePage getFileTypePage() {
		return fFileTypePage;
	}

	public CommitWizardCommitPage getCommitPage() {
		return fCommitPage;
	}

	public ModelSynchronizeParticipant getParticipant() {
		return fParticipant;
	}

	@Override
	public boolean canFinish() {
		final IWizardPage current= getContainer().getCurrentPage();
		if (current == fFileTypePage && fCommitPage != null)
			return false;
		return super.canFinish();
	}

	@Override
	public boolean performFinish() {
		
		final String comment= fCommitPage.getComment(getShell());
		if (comment == null)
			return false;
		
		IResource[] resources = AbstractCommitAction.getOutgoingChanges(getDiffTree(), fCommitPage.getTraversalsToCommit(), null);
		if (resources.length == 0)
			return true;
		
		final IResource[] unadded;
		try {
			unadded = getUnaddedResources(resources);
		} catch (CVSException e1) {
			return false;
		}
		
		final IResource[] files = getFiles(resources);
		
		final AddAndCommitOperation operation= new AddAndCommitOperation(getPart(), files, unadded, comment);
		if (jobListener != null)
			operation.setJobChangeListener(jobListener);
		
		if (fFileTypePage != null) {
			final Map extensionsToSave= new HashMap();
			final Map extensionsNotToSave= new HashMap();
			
			fFileTypePage.getModesForExtensions(extensionsToSave, extensionsNotToSave);
			CommitWizardFileTypePage.saveExtensionMappings(extensionsToSave);
			operation.setModesForExtensionsForOneTime(extensionsNotToSave);
			
			final Map namesToSave= new HashMap();
			final Map namesNotToSave= new HashMap();
			
			fFileTypePage.getModesForNames(namesToSave, namesNotToSave);
			CommitWizardFileTypePage.saveNameMappings(namesToSave);
			operation.setModesForNamesForOneTime(namesNotToSave);
		}
		
		try {
			operation.run();
		} catch (InvocationTargetException e) {
			return false;
		} catch (InterruptedException e) {
			return false;
		}
		
		fCommitPage.finish();
		return super.performFinish();
	}
	
	@Override
	public boolean performCancel() {
		fCommitPage.finish();
		return super.performCancel();
	}

	@Override
	public void addPages() {
		
		final Collection<String> names = new HashSet<>();
		final Collection<String> extensions = new HashSet<>();
		getUnknownNamesAndExtension(fUnaddedDiffs, names, extensions);
		
		if (names.size() + extensions.size() > 0) {
			fFileTypePage= new CommitWizardFileTypePage(extensions, names); 
			addPage(fFileTypePage);
		}
		
		fCommitPage= new CommitWizardCommitPage(fResources, this);
		addPage(fCommitPage);
		
		super.addPages();
	}

	@Override
	public void dispose() {
		fParticipant.dispose();
		super.dispose();
	}
	
	public static void run(IWorkbenchPart part, Shell shell, IResource [] resources) throws CVSException {
		try {
			CommitWizard commitWizard = new CommitWizard(resources);
			commitWizard.setPart(part);
			run(shell, commitWizard);
		} catch (OperationCanceledException e) {
			// Ignore
		}
	}
	
	private void setPart(IWorkbenchPart part) {
		this.part = part;
	}

	public static void run(Shell shell, SyncInfoSet infos, IJobChangeListener jobListener) throws CVSException {
		try {
			run(shell, new CommitWizard(infos, jobListener));
		} catch (OperationCanceledException e) {
			// Ignore
		}
	}
	
	public static void run(IWorkbenchPart part, Shell shell, final ResourceTraversal[] traversals) throws CVSException {
		try {
			final IResource [][] resources = new IResource[][] { null };
			PlatformUI.getWorkbench().getProgressService().busyCursorWhile(monitor -> {
				try {
					resources[0] = getDeepResourcesToCommit(traversals, monitor);
				} catch (CoreException e) {
					throw new InvocationTargetException(e);
				}
			});
			run(part, shell, resources[0]);
		} catch (OperationCanceledException e) {
			// Ignore
		} catch (InvocationTargetException e) {
			throw CVSException.wrapException(e);
		} catch (InterruptedException e) {
			// Ignore
		}
	}

	private IWorkbenchPart getPart() {
		if (part != null)
			return part;
		return PlatformUI.getWorkbench().getActiveWorkbenchWindow().getPartService().getActivePart();
	}
	
	private static void run(Shell shell, CommitWizard wizard) {
		if (!wizard.hasOutgoingChanges()) {
			MessageDialog.openInformation(shell, CVSUIMessages.CommitWizard_6, CVSUIMessages.CommitWizard_7); // 
		} else {
			int highestProblemSeverity = wizard.getHighestProblemSeverity();
			IPreferenceStore preferenceStore = CVSUIPlugin.getPlugin().getPreferenceStore();
			switch (highestProblemSeverity) {
			case IMarker.SEVERITY_WARNING:
				String allowCommitsWithWarnings = preferenceStore.getString(ICVSUIConstants.PREF_ALLOW_COMMIT_WITH_WARNINGS);
				if (MessageDialogWithToggle.PROMPT.equals(allowCommitsWithWarnings) || MessageDialogWithToggle.NEVER.equals(allowCommitsWithWarnings)) {
					MessageDialogWithToggle warningDialog = MessageDialogWithToggle.openYesNoQuestion(shell, CVSUIMessages.CommitWizard_8, CVSUIMessages.CommitWizard_9, CVSUIMessages.CommitWizard_10, false, preferenceStore, ICVSUIConstants.PREF_ALLOW_COMMIT_WITH_WARNINGS);
					if (IDialogConstants.YES_ID != warningDialog.getReturnCode()) {
						return;
					}
				}
				break;
			case IMarker.SEVERITY_ERROR:
				String allowCommitsWithErrors = preferenceStore.getString(ICVSUIConstants.PREF_ALLOW_COMMIT_WITH_ERRORS);
				if (MessageDialogWithToggle.PROMPT.equals(allowCommitsWithErrors) || MessageDialogWithToggle.NEVER.equals(allowCommitsWithErrors)) {
					MessageDialogWithToggle errorDialog = MessageDialogWithToggle.openYesNoQuestion(shell, CVSUIMessages.CommitWizard_11, CVSUIMessages.CommitWizard_12, CVSUIMessages.CommitWizard_13, false, preferenceStore, ICVSUIConstants.PREF_ALLOW_COMMIT_WITH_ERRORS);
					if (IDialogConstants.YES_ID != errorDialog.getReturnCode()) {
						return;
					}
				}
				break;
			}
			open(shell, wizard);
		}
	}

	protected static int open(Shell shell, ResizableWizard wizard) {
		final WizardDialog dialog= new WizardDialog(shell, wizard);
		dialog.setPageSize(wizard.loadSize());
		return dialog.open();
	}
	
	private void getUnknownNamesAndExtension(IResource[] resources, Collection<String> names,
			Collection<String> extensions) {

		final IFileContentManager manager= Team.getFileContentManager();

		for (int i = 0; i < resources.length; i++) {

			IResource local = resources[i];
			if (local instanceof IFile && manager.getType((IFile)local) == Team.UNKNOWN) {
				final String extension= local.getFileExtension();
				if (extension != null && !manager.isKnownExtension(extension)) {
					extensions.add(extension);
				}

				final String name= local.getName();
				if (extension == null && name != null && !manager.isKnownFilename(name))
					names.add(name);
			}
		}
	}
	
	private IResource[] getUnaddedResources(IResource[] resources) throws CVSException {
		List/* <IResource> */<IResource> unadded = new ArrayList<>();
		for (int i = 0; i < resources.length; i++) {
			if (!isAdded(resources[i])) {
				unadded.add(resources[i]);
			}
		}
		return unadded.toArray(new IResource[0]);
	}

	private IResource[] getFiles(IResource[] resources) {
		final List<IResource> files = new ArrayList<>();
		for (int i = 0; i < resources.length; i++) {
			if (resources[i].getType() == IResource.FILE)
				files.add(resources[i]);
		}
		return files.toArray(new IResource[0]);
	}
	
	private static boolean isAdded(IResource resource) throws CVSException {
		final ICVSResource cvsResource = CVSWorkspaceRoot.getCVSResourceFor(resource);
		if (cvsResource.isFolder()) {
			return ((ICVSFolder)cvsResource).isCVSFolder();
		}
		return cvsResource.isManaged();
	}

	private static IResource[] getDeepResourcesToCommit(ResourceTraversal[] traversals, IProgressMonitor monitor) throws CoreException {
		List<IResource> roots = new ArrayList<>();
		for (int j = 0; j < traversals.length; j++) {
			ResourceTraversal traversal = traversals[j];
			IResource[] resources = traversal.getResources();
			if (traversal.getDepth() == IResource.DEPTH_INFINITE) {
				roots.addAll(Arrays.asList(resources));
			} else if (traversal.getDepth() == IResource.DEPTH_ZERO) {
				collectShallowFiles(resources, roots);
			} else if (traversal.getDepth() == IResource.DEPTH_ONE) {
				collectShallowFiles(resources, roots);
				for (int k = 0; k < resources.length; k++) {
					IResource resource = resources[k];
					if (resource.getType() != IResource.FILE) {
						collectShallowFiles(members(resource), roots);
					}
				}
			}
		}
		return roots.toArray(new IResource[roots.size()]);
	}

	private static IResource[] members(IResource resource) throws CoreException {
		return CVSProviderPlugin.getPlugin().getCVSWorkspaceSubscriber().members(resource);
	}

	private static void collectShallowFiles(IResource[] resources, List<IResource> roots) {
		for (int k = 0; k < resources.length; k++) {
			IResource resource = resources[k];
			if (resource.getType() == IResource.FILE)
				roots.add(resource);
		}
	}
}    

