/*******************************************************************************
 * 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
 *******************************************************************************/
package org.eclipse.team.internal.ccvs.ui.wizards;


import java.lang.reflect.InvocationTargetException;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.*;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.wizard.IWizardPage;
import org.eclipse.jface.wizard.Wizard;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.team.core.RepositoryProvider;
import org.eclipse.team.core.TeamException;
import org.eclipse.team.internal.ccvs.core.*;
import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot;
import org.eclipse.team.internal.ccvs.core.syncinfo.FolderSyncInfo;
import org.eclipse.team.internal.ccvs.core.util.KnownRepositories;
import org.eclipse.team.internal.ccvs.ui.*;
import org.eclipse.team.internal.ccvs.ui.Policy;
import org.eclipse.team.internal.ccvs.ui.operations.*;
import org.eclipse.team.internal.ccvs.ui.tags.*;
import org.eclipse.team.internal.ui.Utils;
import org.eclipse.team.ui.IConfigurationWizard;
import org.eclipse.team.ui.synchronize.ModelSynchronizeParticipant;
import org.eclipse.ui.IWorkbench;

/**
 * This wizard helps the user to import a new project in their workspace
 * into a CVS repository for the first time.
 */
public class SharingWizard extends Wizard implements IConfigurationWizard, ICVSWizard {
	// The project to configure
	private IProject project;

	// The autoconnect page is used if CVS/ directories already exist.
	private ConfigurationWizardAutoconnectPage autoconnectPage;
	
	// The import page is used if CVS/ directories do not exist.
	private RepositorySelectionPage locationPage;
	
	// The page that prompts the user for connection information.
	private ConfigurationWizardMainPage createLocationPage;
	
	// The page that prompts the user for module name.
	private ModuleSelectionPage modulePage;

	// The page that lets the user pick a branch to share against
	private TagSelectionWizardPage tagPage;
	
	// The page that allows the user to commit or update resources
	private SharingWizardSyncPage syncPage;
	
	// Keep track of location state so we know what to do at the end
	private ICVSRepositoryLocation location;
	private boolean isNewLocation;
	
	// Keep track of the folder that existed the last time we checked
	private ICVSRemoteFolder existingRemote;

	private ICVSRemoteFolder remoteFolder;
	
	public SharingWizard() {
		IDialogSettings cvsSettings = CVSUIPlugin.getPlugin().getDialogSettings();
		IDialogSettings section = cvsSettings.getSection("SharingWizard");//$NON-NLS-1$
		if (section == null) {
			section = cvsSettings.addNewSection("SharingWizard");//$NON-NLS-1$
		}
		setDialogSettings(section);
		setNeedsProgressMonitor(true);
		setWindowTitle(CVSUIMessages.SharingWizard_title); 
	}	
		
	@Override
	public void addPages() {
		ImageDescriptor sharingImage = CVSUIPlugin.getPlugin().getImageDescriptor(ICVSUIConstants.IMG_WIZBAN_SHARE);
		boolean autoconnect = false;
		if (doesCVSDirectoryExist()) {
			autoconnectPage = new ConfigurationWizardAutoconnectPage("autoconnectPage", CVSUIMessages.SharingWizard_autoConnectTitle, sharingImage); //$NON-NLS-1$ 
			if (autoconnectPage.setProject(project)) {
				autoconnectPage.setDescription(CVSUIMessages.SharingWizard_autoConnectTitleDescription); 
				addPage(autoconnectPage);
				autoconnect = true;
			}
		}
		if (!autoconnect) {
			ICVSRepositoryLocation[] locations = CVSUIPlugin.getPlugin().getRepositoryManager().getKnownRepositoryLocations();
			if (locations.length > 0) {
				locationPage = new RepositorySelectionPage("importPage", CVSUIMessages.SharingWizard_importTitle, sharingImage); //$NON-NLS-1$ 
				locationPage.setDescription(CVSUIMessages.SharingWizard_importTitleDescription); 
				addPage(locationPage);
			}
			createLocationPage = new ConfigurationWizardMainPage("createLocationPage", CVSUIMessages.SharingWizard_enterInformation, sharingImage); //$NON-NLS-1$ 
			createLocationPage.setDescription(CVSUIMessages.SharingWizard_enterInformationDescription); 
			createLocationPage.setCVSWizard(this);
			createLocationPage.setDialogSettings(NewLocationWizard.getLocationDialogSettings());
			addPage(createLocationPage);
			modulePage = new ModuleSelectionPage("modulePage", CVSUIMessages.SharingWizard_enterModuleName, sharingImage); //$NON-NLS-1$ 
			modulePage.setDescription(CVSUIMessages.SharingWizard_enterModuleNameDescription); 
			modulePage.setCVSWizard(this);
			modulePage.setProject(project);
			modulePage.setHelpContxtId(IHelpContextIds.SHARING_MODULE_PAGE);
			addPage(modulePage);
			
			addTagPage(sharingImage);
			addSyncPage(sharingImage);
		}
	}
	
	private void addTagPage(ImageDescriptor sharingImage) {
		tagPage = new TagSelectionWizardPage("tagPage",  //$NON-NLS-1$
			CVSUIMessages.SharingWizard_selectTagTitle,  
			sharingImage,
			CVSUIMessages.SharingWizard_selectTag, 
			TagSource.EMPTY, // start with an empty tag source
			TagSourceWorkbenchAdapter.INCLUDE_HEAD_TAG | TagSourceWorkbenchAdapter.INCLUDE_BRANCHES); 
		tagPage.setCVSWizard(this);
		tagPage.setHelpContxtId(IHelpContextIds.SHARING_TAG_SELETION_PAGE);
		addPage(tagPage);
	}
	
	private void addSyncPage(ImageDescriptor sharingImage) {
		syncPage = new SharingWizardSyncPage("syncPagePage",  //$NON-NLS-1$
			CVSUIMessages.SharingWizard_23,  
			sharingImage,
			CVSUIMessages.SharingWizard_24); 
		syncPage.setProject(project);
		syncPage.setCVSWizard(this);
		addPage(syncPage);
	}
	
	@Override
	public boolean canFinish() {
		IWizardPage page = getContainer().getCurrentPage();
		return (page == autoconnectPage || page == syncPage);
	}
	
	@Override
	public IWizardPage getNextPage(IWizardPage page) {
		// Assume the page is about to be shown when this method is
		// invoked
		return getNextPage(page, true /* about to show*/);
	}
	
	@Override
	public IWizardPage getNextPage(IWizardPage page, boolean aboutToShow) {
		if (page == autoconnectPage) return null;
		if (page == locationPage) {
			if (locationPage.getLocation() == null) {
				return createLocationPage;
			} else {
				if (aboutToShow) {
					try {
						modulePage.setLocation(getLocation());
					} catch (TeamException e1) {
						CVSUIPlugin.log(e1);
					}
				}
				return modulePage;
			}
		}
		if (page == createLocationPage) {
			if (aboutToShow) {
				try {
					modulePage.setLocation(getLocation());
				} catch (TeamException e1) {
					CVSUIPlugin.log(e1);
				}
			}
			return modulePage;
		}
		try {
			if (page == modulePage) {
				if (aboutToShow) {
					remoteFolder = null; // reset
					getRemoteFolder(); // initialize remoteFolder
					if (exists(remoteFolder)) {
						prepareTagPage(remoteFolder);
						return tagPage;
					} else {
						try {
							populateSyncPage(false /* remote doesn't exist */);
						} catch (InvocationTargetException e) {
							CVSUIPlugin.openError(getShell(), null, null, e);
							if (!RepositoryProvider.isShared(project)) {
								// Only stay on the current page if the sharing was a total failure
								return null;
							}
						}
						return syncPage;
					}
				} else {
					return syncPage;
				}
			}
			if (page == tagPage) {
				if (aboutToShow) {
					remoteFolder = null; // reset
					getRemoteFolder(); // initialize remoteFolder
					populateSyncPage(true /* remote exists */);
				}
				return syncPage;
			}
		} catch (InvocationTargetException e) {
			// Show the error and fall through to return null as the next page
			CVSUIPlugin.openError(getShell(), null, null, e);
		} catch (InterruptedException e) {
			// The user cancelled. Fall through and return null as the next page.
		}
		return null;
	}

	/*
	 * @see IWizard#performFinish
	 */
	@Override
	public boolean performFinish() {
		final boolean[] result = new boolean[] { true };
		if (isAutoconnect()) {
			try {
				getContainer().run(true /* fork */, true /* cancel */, monitor -> {
					try {
						result[0] = autoconnectCVSProject(monitor);
					} catch (TeamException e) {
						throw new InvocationTargetException(e);
					} finally {
						monitor.done();
					}
				});
			} catch (InterruptedException e) {
				return true;
			} catch (InvocationTargetException e) {
				CVSUIPlugin.openError(getContainer().getShell(), null, null, e);
				result[0] = false;
			}
		}
		// Add the location to the provider if it is new
		if (result[0] && isNewLocation) {
			KnownRepositories.getInstance().addRepository(location, true /* broadcast */);
		}
		
		final Shell parentShell= getShell().getParent().getShell();
		if (getContainer().getCurrentPage() == syncPage) {
			syncPage.saveSettings();
			if (syncPage.commitChanges()) {
				Display.getCurrent().asyncExec(() -> {
					try {
						CommitWizard.run(null, parentShell, new IResource[] { syncPage.getProject() });
					} catch (CVSException e) {
						// TODO:handle
						CVSUIPlugin.log(e);
					}
				});
			}
		}
		return result[0];
	}

	@Override
	public boolean performCancel() {
		boolean disposeLocation = isNewLocation;
		ICVSRepositoryLocation location;
		try {
			location = getLocation();
		} catch (TeamException e) {
			CVSUIPlugin.log(e);
			return true;
		}
		if (location == null) return true;
		// If on the last page, offer to disconnect
		if (getContainer().getCurrentPage() == syncPage
				&& RepositoryProvider.getProvider(project) != null) {
			// Prompt to see if we should undo out work
			if (promptToKeepMapping()) {
				// If we didn't disconnect, don't dispose the repo
				disposeLocation = false;
				// Add the location to the provider if it is new
				if (isNewLocation) {
					KnownRepositories.getInstance().addRepository(location, true /* broadcast */);
				}
			} else {
				try {
					getContainer().run(true, true,
							monitor -> new DisconnectOperation(null, new IProject[] { project }, true).run(monitor));
				} catch (InvocationTargetException e) {
					CVSUIPlugin.log(IStatus.ERROR, e.getMessage(), e.getTargetException());
				} catch (InterruptedException e) {
					// Ignore
				}
			}
		}
		// Dispose of the location if appropriate
		if (disposeLocation) {
			KnownRepositories.getInstance().disposeRepository(location);
		}
		return super.performCancel();
	}

	private boolean promptToKeepMapping() {
		return (MessageDialog.openQuestion(getShell(), CVSUIMessages.SharingWizard_26, NLS.bind(CVSUIMessages.SharingWizard_27, new String[] { project.getName() }))); // 
	}

	private void reconcileProject(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
		new ReconcileProjectOperation(getShell(), project, getRemoteFolder()).run(monitor);
	}
	
	/**
	 * Return an ICVSRepositoryLocation
	 */
	private ICVSRepositoryLocation getLocation() throws TeamException {
		// If there is an autoconnect page then it has the location
		if (autoconnectPage != null) {
			return recordLocation(autoconnectPage.getLocation());
		}
		
		// If the location page has a location, use it.
		if (locationPage != null) {
			ICVSRepositoryLocation newLocation = locationPage.getLocation();
			if (newLocation != null) {
				return recordLocation(newLocation);
			}
		}
		
		// Otherwise, get the location from the create location page
		final ICVSRepositoryLocation[] locations = new ICVSRepositoryLocation[] { null };
		final CVSException[] exception = new CVSException[] { null };
		getShell().getDisplay().syncExec(() -> {
			try {
				locations[0] = createLocationPage.getLocation();
			} catch (CVSException e) {
				exception[0] = e;
			}
		});
		if (exception[0] != null) {
			throw exception[0];
		}
		return recordLocation(locations[0]);
	}

	private ICVSRepositoryLocation recordLocation(ICVSRepositoryLocation newLocation) {
		if (newLocation == null) return location;
		if (location == null || !newLocation.equals(location)) {
			if (location != null && isNewLocation) {
				// Dispose of the previous location
				KnownRepositories.getInstance().disposeRepository(location);
			}
			location = newLocation;
			isNewLocation = !KnownRepositories.getInstance().isKnownRepository(newLocation.getLocation(false));
			if (isNewLocation) {
				// Add the location silently so we can work with it
				location = KnownRepositories.getInstance().addRepository(location, false /* silently */);
			}
		}
		return location;
	}
	
	/*
	 * @see IConfigurationWizard#init(IWorkbench, IProject)
	 */
	@Override
	public void init(IWorkbench workbench, IProject project) {
		this.project = project;
	}
	
	private boolean doesCVSDirectoryExist() {
		// Determine if there is an existing CVS/ directory from which configuration
		// information can be retrieved.
		Shell shell = null;
		if (getContainer() != null) {
			shell = getContainer().getShell();
		}
		final boolean[] isCVSFolder = new boolean[] { false };
		try {
			CVSUIPlugin.runWithRefresh(shell, new IResource[] { project }, monitor -> {
				try {
					ICVSFolder folder = (ICVSFolder) CVSWorkspaceRoot.getCVSResourceFor(project);
					FolderSyncInfo info = folder.getFolderSyncInfo();
					isCVSFolder[0] = info != null;
				} catch (final TeamException e) {
					throw new InvocationTargetException(e);
				}
			}, null);
		} catch (InvocationTargetException e) {
			CVSUIPlugin.openError(shell, null, null, e);
		} catch (InterruptedException e) {
			// Cancelled. Just fall through
		}
		return isCVSFolder[0];
	}
	
	/*
	 * Should the project be auto-connected
	 */
	/* private*/ boolean isAutoconnect() {
		return autoconnectPage != null && doesCVSDirectoryExist();
	}
	
	/*
	 * Auto-connect to the repository using CVS/ directories
	 */
	/*private */ boolean autoconnectCVSProject(IProgressMonitor monitor) throws TeamException {
		try {
			monitor.beginTask(null, 100);
			
			FolderSyncInfo info = autoconnectPage.getFolderSyncInfo();
			if (info == null) {
				// Error!
				return false;
			}
			
			// Get the repository location (the get will add the location to the provider)
			ICVSRepositoryLocation location = getLocation();
	
			// Validate the connection if the user wants to
			boolean validate = autoconnectPage.getValidate();					
			if (validate) {
				// Do the validation
				try {
					location.validateConnection(Policy.subMonitorFor(monitor, 50));
				} catch (final TeamException e) {
					// Exception validating. We can continue if the user wishes.
					final boolean[] keep = new boolean[] { false };
					getShell().getDisplay()
							.syncExec(() -> keep[0] = MessageDialog.openQuestion(getContainer().getShell(),
									CVSUIMessages.SharingWizard_validationFailedTitle,
									NLS.bind(CVSUIMessages.SharingWizard_validationFailedText,
											(new Object[] { e.getStatus().getMessage() }))));
					if (!keep[0]) {
						return false;
					}
					// They want to keep the connection anyway. Fall through.
				}
			}
			
			// Set the sharing
			CVSWorkspaceRoot.setSharing(project, info, Policy.subMonitorFor(monitor, 50));
			return true;
		} finally {
			monitor.done();
		}
	}
	
	private boolean shareProject(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
		monitor.beginTask(null, 100);
		ICVSRepositoryLocation location = null;
		try {
			location = getLocation();
			location.validateConnection(Policy.subMonitorFor(monitor, 50));
		} catch (TeamException e) {
			CVSUIPlugin.openError(getShell(), null, null, e, CVSUIPlugin.PERFORM_SYNC_EXEC);
			if (isNewLocation && location != null) location.flushUserInfo();
			return false;
		}
		
		// Create the remote module for the project
		ShareProjectOperation op = new ShareProjectOperation(null, location, project, getRemoteFolder().getRepositoryRelativePath());
		op.setShell(getShell());
		op.run(Policy.subMonitorFor(monitor, 50));
		return true;
	}
	
	private CVSTag getTag() {
		if (tagPage == null || tagPage.getSelectedTag() == null) {
			return CVSTag.DEFAULT;
		}
		return tagPage.getSelectedTag();
	}
	
	private ICVSRemoteFolder getRemoteFolder() {
		if (remoteFolder == null) {
			ICVSRemoteFolder folder = modulePage.getSelectedModule();
			remoteFolder = (ICVSRemoteFolder)folder.forTag(getTag());
		}
		return remoteFolder;
	}
	
	private boolean exists(ICVSRemoteFolder folder, IProgressMonitor monitor) throws TeamException {
		if (existingRemote != null && existingRemote.equals(folder)) return true;
		if (folder.exists(monitor)) {
			existingRemote = folder;
			return true;
		} else {
			existingRemote = null;
			return false;
		}
	}
	
	private boolean exists(final ICVSRemoteFolder folder) throws InvocationTargetException, InterruptedException {
		final boolean[] result = new boolean[] { false };
		getContainer().run(true, true, monitor -> {
			try {
				result[0] = exists(folder, monitor);
			} catch (TeamException e) {
				throw new InvocationTargetException(e);
			}
		});
		return result[0];
	}
	
	private void populateSyncPage(final boolean exists) throws InvocationTargetException, InterruptedException {
		getContainer().run(true, true, monitor -> {
			monitor.beginTask(null, IProgressMonitor.UNKNOWN);
			if (exists) {
				reconcileProject(Policy.subMonitorFor(monitor, 50));
			} else {
				shareProject(Policy.subMonitorFor(monitor, 50));
			}
			try {
				getParticipant().getContext().refresh(Utils.getResourceMappings(new IProject[] { project }),
						Policy.subMonitorFor(monitor, 50));
			} catch (CoreException e) {
				throw new InvocationTargetException(e);
			}
			if (monitor.isCanceled()) {
				throw new InterruptedException();
			}
			monitor.done();
		});
	}
	
	@Override
	public IWizardPage getPreviousPage(IWizardPage page) {
		if (page == syncPage) {
			// There's no going back from the sync page
			return null;
		}
		return super.getPreviousPage(page);
	}
	
	private void prepareTagPage(ICVSRemoteFolder remote) {
		tagPage.setTagSource(TagSource.create(remote));
		tagPage.setDescription(NLS.bind(CVSUIMessages.SharingWizard_25, new String[] { remote.getRepositoryRelativePath() })); 
	}

	private ModelSynchronizeParticipant getParticipant() {
		return syncPage.getParticipant();
	}
}
