/*******************************************************************************
 * Copyright (c) 2000, 2016 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.releng.tools;

import java.lang.reflect.InvocationTargetException;
import java.util.HashSet;
import java.util.Set;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.window.Window;
import org.eclipse.jface.wizard.IWizardPage;
import org.eclipse.jface.wizard.Wizard;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.osgi.util.NLS;
import org.eclipse.releng.tools.preferences.MapProjectPreferencePage;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.ControlListener;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.team.core.TeamException;
import org.eclipse.team.internal.ccvs.core.CVSTag;
import org.eclipse.team.internal.ccvs.core.client.Command;
import org.eclipse.team.internal.ccvs.ui.CVSLightweightDecorator;
import org.eclipse.team.internal.ccvs.ui.CVSUIPlugin;
import org.eclipse.team.internal.ccvs.ui.operations.CommitOperation;
import org.eclipse.team.internal.ccvs.ui.operations.RepositoryProviderOperation;
import org.eclipse.team.internal.ui.ITeamUIImages;
import org.eclipse.team.internal.ui.TeamUIPlugin;
import org.eclipse.team.internal.ui.dialogs.IPromptCondition;
import org.eclipse.team.internal.ui.dialogs.PromptingDialog;


public class ReleaseWizard extends Wizard {

	// Dialog store constants
	private static final String BOUNDS_HEIGHT= "bounds.height"; //$NON-NLS-1$
	private static final String BOUNDS_WIDTH= "bounds.width"; //$NON-NLS-1$
	private static final String BOUNDS_Y= "bounds.y"; //$NON-NLS-1$
	private static final String BOUNDS_X= "bounds.x"; //$NON-NLS-1$
	
	private MapProjectSelectionPage mapSelectionPage;
	private ProjectSelectionPage projectSelectionPage;
	private TagPage tagPage;
	private ProjectComparePage projectComparePage;
	private MapFileComparePage mapComparePage;
	private CommitCommentPage commentPage;
	private BuildNotesPage buildNotesPage;
	private ValidatePage validatePage;

	private Dialog parentDialog;
	private IDialogSettings section;
	
	private MapProject mapProject;
	private IProject[] preSelectedProjects;
	private IProject[] selectedProjects;
	private IPreferenceStore preferenceStore;
	private boolean defaultBeingUsed;
	

	public ReleaseWizard() {
		setWindowTitle("Release"); //$NON-NLS-1$
		IDialogSettings settings = RelEngPlugin.getDefault().getDialogSettings();
		section = settings.getSection("ReleaseWizard");//$NON-NLS-1$
		if (section == null) {
			section = settings.addNewSection("ReleaseWizard");//$NON-NLS-1$
		}
		setDialogSettings(section);
		preferenceStore = RelEngPlugin.getDefault().getPreferenceStore();
	}
	
	/*
	 * @see org.eclipse.jface.wizard.Wizard#createPageControls(org.eclipse.swt.widgets.Composite)
	 * @since 3.1
	 */
	@Override
	public void createPageControls(Composite pageContainer) {
		super.createPageControls(pageContainer);

		if (getDialogSettings().get(BOUNDS_X) != null) {
			int x= getDialogSettings().getInt(BOUNDS_X);
			int y= getDialogSettings().getInt(BOUNDS_Y);
			int width= getDialogSettings().getInt(BOUNDS_WIDTH);
			int height= getDialogSettings().getInt(BOUNDS_HEIGHT);
			getShell().setBounds(x, y, width, height);
		}
		
		getShell().addControlListener(new ControlListener() {

			@Override
			public void controlMoved(ControlEvent e) {
				storeBounds(e);
			}

			@Override
			public void controlResized(ControlEvent e) {
				storeBounds(e);
			}
			
			private void storeBounds(ControlEvent e) {
				Rectangle bounds= getShell().getBounds();
				getDialogSettings().put(BOUNDS_X, bounds.x);
				getDialogSettings().put(BOUNDS_Y, bounds.y);
				getDialogSettings().put(BOUNDS_WIDTH, bounds.width);
				getDialogSettings().put(BOUNDS_HEIGHT, bounds.height);
			}
		});
	}

	public boolean execute(Shell shell) {
		setNeedsProgressMonitor(true);
		WizardDialog dialog = new WizardDialog(shell, this);
		setParentDialog(dialog);
		return (dialog.open() == Window.OK);
	}
	
	/**
	 * @see org.eclipse.jface.wizard.IWizard#addPages()
	 */
	@Override
	public void addPages() {
		defaultBeingUsed = false;
		if (preferenceStore.getBoolean(MapProjectPreferencePage.USE_DEFAULT_MAP_PROJECT) &&
				(preferenceStore.getString(MapProjectPreferencePage.SELECTED_MAP_PROJECT_PATH).length() > 1)) {
			String path = preferenceStore.getString(MapProjectPreferencePage.SELECTED_MAP_PROJECT_PATH);
			
			try {
				mapProject = new MapProject(ResourcesPlugin.getWorkspace().getRoot().getProject(path));
				defaultBeingUsed = true;
			}
			catch (CoreException e) {
				//this is ok, we will use the mapSelectionPage instead
			}			
		}

		ImageDescriptor wizardPageImageDescriptor = TeamUIPlugin
				.getImageDescriptor(ITeamUIImages.IMG_WIZBAN_SHARE);

		if (!defaultBeingUsed)
			addMapSelectionPage(wizardPageImageDescriptor);
		
		projectSelectionPage = new ProjectSelectionPage("ProjectSelectionPage", //$NON-NLS-1$
				Messages.getString("ReleaseWizard.6"), //$NON-NLS-1$
				section, wizardPageImageDescriptor);
		projectSelectionPage.setDescription(Messages
				.getString("ReleaseWizard.7")); //$NON-NLS-1$
		addPage(projectSelectionPage);
		
		tagPage = new TagPage("TagPage", //$NON-NLS-1$
				Messages.getString("ReleaseWizard.9"), //$NON-NLS-1$
				section, 
				wizardPageImageDescriptor);
		tagPage.setDescription(Messages.getString("ReleaseWizard.10")); //$NON-NLS-1$
		addPage(tagPage);
		
		projectComparePage = new ProjectComparePage("ProjectComparePage", //$NON-NLS-1$
				Messages.getString("ReleaseWizard.12"), //$NON-NLS-1$
				section,
				wizardPageImageDescriptor);
		projectComparePage.setDescription(Messages.getString("ReleaseWizard.13")); //$NON-NLS-1$
		addPage(projectComparePage);
		
		buildNotesPage = new BuildNotesPage("Build Notes Page", //$NON-NLS-1$
				Messages.getString("ReleaseWizard.1"), //$NON-NLS-1$
				section,
				wizardPageImageDescriptor);
		buildNotesPage.setDescription(Messages.getString("ReleaseWizard.0")); //$NON-NLS-1$
		addPage(buildNotesPage);
		
		mapComparePage = new MapFileComparePage("MapComparePage", //$NON-NLS-1$
				Messages.getString("ReleaseWizard.15"),  //$NON-NLS-1$
				wizardPageImageDescriptor);
		mapComparePage.setDescription(Messages.getString("ReleaseWizard.16")); //$NON-NLS-1$
		addPage(mapComparePage);
		
		commentPage = new CommitCommentPage(parentDialog, "Commit", //$NON-NLS-1$
				Messages.getString("ReleaseWizard.18"), //$NON-NLS-1$
				wizardPageImageDescriptor,
				Messages.getString("ReleaseWizard.19")); //$NON-NLS-1$
		addPage(commentPage);
		
		validatePage = new ValidatePage(parentDialog, "ValidatePage", //$NON-NLS-1$
				Messages.getString("ReleaseWizard.validatePageTitle"), //$NON-NLS-1$
				wizardPageImageDescriptor);
		addPage(validatePage);
		
		if (defaultBeingUsed) broadcastMapProjectChange(mapProject);
	}

	/*
	 * @see org.eclipse.jface.wizard.Wizard#dispose()
	 * @since 3.7
	 */
	@Override
	public void dispose() {
		if (mapProject != null) {
			mapProject.dispose();
			mapProject= null;
		}
		super.dispose();
	}

	private void addMapSelectionPage(ImageDescriptor wizardPageImageDescriptor) {
		mapSelectionPage = new MapProjectSelectionPage(
				"MapProjectSelectionPage", //$NON-NLS-1$
				Messages.getString("ReleaseWizard.4"), //$NON-NLS-1$
				section, wizardPageImageDescriptor);
		mapSelectionPage.setDescription(Messages.getString("ReleaseWizard.3")); //$NON-NLS-1$
		addPage(mapSelectionPage);
	}

	/*
	 * commit buildnotes file if update option selected
	 */
    public boolean buildNotesOperation() {
		if (buildNotesPage.isUpdateNotesButtonChecked() && projectComparePage.isBuildNotesButtonChecked()) {
			buildNotesPage.updateNotesFile();
			try {
				getContainer().run(true, true, monitor -> {
					IFile iFile = buildNotesPage.getIFile();
					IProject iProject = iFile.getProject();
					monitor.beginTask(Messages.getString("ReleaseWizard.20"), 100); //$NON-NLS-1$
					new CommitOperation(null,
							RepositoryProviderOperation.asResourceMappers(new IResource[] { iProject }),
							new Command.LocalOption[0], commentPage.getComment()).run(monitor);
					monitor.done();
				});
			} catch (InterruptedException e) {
				// Cancelled.
				return false;
			} catch (InvocationTargetException e) {
				CVSUIPlugin.openError(getShell(), null, null, e);
			}
			checkProjects();
		}
		return true;
	}

    /*
     * add project of build notes file if not already in selected projects
     */
	public void checkProjects() {
		IProject[] temp = new IProject[selectedProjects.length + 1];
		for (int i = 0; i < selectedProjects.length; i++) {
			if (selectedProjects[i] == buildNotesPage.getIFile().getProject()) {
				return;
			}
		}
		System.arraycopy(selectedProjects, 0, temp, 0, selectedProjects.length);
		temp[temp.length - 1] = buildNotesPage.getIFile().getProject();
		selectedProjects = temp;
	}
	
	/**
	 * @see org.eclipse.jface.wizard.Wizard#performFinish()
	 */
	@Override
	public boolean performFinish() {
		if(!isProjectSelected())return false;
		
		if (projectSelectionPage.isCompareButtonChecked() && !buildNotesOperation()) {
			return true; // Build notes file update cancelled. Close dialog.
		}

		try {
			getContainer().run(true, true, monitor -> {
				CVSTag tag = new CVSTag(tagPage.getTagString(), CVSTag.VERSION);
				TagAndReleaseOperation operation = new TagAndReleaseOperation(null, mapProject, selectedProjects, tag,
						commentPage.getComment());
				if (tagPage.isMoveButtonSelected()) {
					operation.moveTag();
				}
				monitor.beginTask(Messages.getString("ReleaseWizard.21"), 100); //$NON-NLS-1$
				operation.run(SubMonitor.convert(monitor, 90));
				if (operation.isMapFileUpdated()) {
					try {
						if (tagPage.isValidateButtonSelected()) {
							try {
								getShell().getDisplay().asyncExec(() -> {
									if (parentDialog instanceof WizardDialog)
										((WizardDialog) parentDialog).showPage(validatePage);
								});
								validateRelease(SubMonitor.convert(monitor, 10));
							} catch (TeamException e) {
								throw new InvocationTargetException(e);
							}
						}
					} finally {
						monitor.done();
					}
				} else {
					// The map file update didn't occur and no exception was
					// thrown.
					// Let the user know of the failure
					IStatus[] errors = operation.getErrors();
					IStatus status;
					if (errors.length == 0) {
						status = new Status(IStatus.ERROR, RelEngPlugin.ID, 0, Messages.getString("ReleaseWizard.22"), //$NON-NLS-1$
								null);
					} else if (errors.length == 1) {
						status = errors[0];
					} else {
						status = new MultiStatus(RelEngPlugin.ID, 0, errors, Messages.getString("ReleaseWizard.23"), //$NON-NLS-1$
								null);
					}
					ErrorDialog.openError(getShell(), Messages.getString("ReleaseWizard.24"), //$NON-NLS-1$
							Messages.getString("ReleaseWizard.25"), //$NON-NLS-1$
							status, IStatus.ERROR | IStatus.WARNING);
				}
			});
			if (!defaultBeingUsed) {
				mapSelectionPage.saveSettings();
				updatePreferenceStore();
			}
			projectSelectionPage.saveSettings();
			projectComparePage.saveSettings();
			buildNotesPage.saveSettings();
			tagPage.saveSettings();
			return true;
		} catch (InterruptedException e) {
			// Cancelled. Ignore and close dialog
			return true;
		} catch (InvocationTargetException e) {
			CVSUIPlugin.openError(getShell(), null, null, e);
		}
		return false;
	}
	
	private void updatePreferenceStore() {
		preferenceStore.setValue(MapProjectPreferencePage.USE_DEFAULT_MAP_PROJECT, mapSelectionPage.useDefaultMapProject());	
		String fullPath = mapSelectionPage.getSelectedMapProject().getProject().getFullPath().toString();
		preferenceStore.setValue(MapProjectPreferencePage.SELECTED_MAP_PROJECT_PATH, fullPath);
	}

	public void setParentDialog(Dialog p) {
		this.parentDialog = p;
	}

	@Override
	public IWizardPage getNextPage(IWizardPage page) {
		if (page == mapSelectionPage) {
			if (selectedProjects == null && preSelectedProjects != null) {
				projectSelectionPage.setSelection(preSelectedProjects);
				selectedProjects= preSelectedProjects;
			}
			return projectSelectionPage;
		}
		if (page == projectSelectionPage) {
			IProject[] projects = projectSelectionPage.getCheckedProjects();
			if (projects != null && projects.length > 0){
				selectedProjects = projects;
			}

			if (projectSelectionPage.isCompareButtonChecked()){
				return projectComparePage;
			}
			else
				return tagPage;
		}
		if (page == tagPage) {
			if (tagPage.compareButtonSelected()){
				mapComparePage.setTag(tagPage.getTagString());
				return mapComparePage;
			}
			if (tagPage.commitButtonSelected())
				return commentPage;
		}
		if (page == mapComparePage)
			return commentPage;
		if (page == projectComparePage) {
			if (projectComparePage.isBuildNotesButtonChecked()) {
				buildNotesPage.setSyncInfoSet(projectComparePage
						.getSyncInfoSet());
				return buildNotesPage;
			} 
			return tagPage;
		}
		if (page == buildNotesPage) {
			return tagPage;
		}
		return null;
	}

	public void setPreSelectedProjects(IResource[] resources) {
		if (resources.length < 1) {
			preSelectedProjects = null;
		} else {
			Set<IProject> list = new HashSet<>();
			for (int i = 0; i < resources.length; i++) {
				list.add(resources[i].getProject());
			}
			preSelectedProjects = list.toArray(new IProject[list.size()]);
		}
	}

	// Prompt for any uncommitted changes
	protected IProject[] performPrompting(IProject[] projects)  {
		IResource[] resources;
		PromptingDialog prompt = new PromptingDialog(getShell(), projects,
			getPromptCondition(projects), Messages.getString("TagAction_uncommittedChangesTitle")); //$NON-NLS-1$
		try {
			 resources = prompt.promptForMultiple();
		} catch(InterruptedException e) {
			return null;
		}
		if(resources.length == 0) {
			return null;					
		}
		projects = new IProject[resources.length ];
		for(int i = 0; i < resources.length; i++){
			if(resources[i] instanceof IProject)
				projects[i] = (IProject)resources[i];
		}
		return projects;
	}
	

	protected IPromptCondition getPromptCondition(IResource[] resources) {
		return new IPromptCondition() {
			@Override
			public boolean needsPrompt(IResource resource) {
				return CVSLightweightDecorator.isDirty(resource);
			}
			@Override
			public String promptMessage(IResource resource) {
				return NLS.bind(Messages.getString("TagAction_uncommittedChanges"), new String[] { resource.getName() }); //$NON-NLS-1$
			}
		};
	}

	public IProject[] getSelectedProjects(){
		return selectedProjects;
	}

	//the update will happen when (1)from project selection page to compare project page or (2)from
	//project selection page to Enter Tag page. It calls shouldRemove() to determine the projects to keep
	public void updateSelectedProject(){
		selectedProjects = projectSelectionPage.getCheckedProjects();
		selectedProjects = performPrompting(selectedProjects);
		projectSelectionPage.setSelection(selectedProjects);
	}
	
	public void setSelectedProjects(IResource[] projects){
		if(projects == null) selectedProjects = null;
		else {
			selectedProjects =  new IProject[projects.length];
			for(int i = 0; i < projects.length; i++){
				selectedProjects[i] = (IProject)projects[i];
			}
		}
	}
	protected ProjectSelectionPage getProjectSelectionPage(){
		return projectSelectionPage;
	}
	
	//This method is called if validate button in TagPage is checked
	private void validateRelease(IProgressMonitor  monitor) throws TeamException{
		ProjectValidationDialog.validateRelease(getShell(), selectedProjects, mapProject.getTagsFor(selectedProjects), monitor);
	}


	private boolean isProjectSelected(){
		if (selectedProjects == null || selectedProjects.length == 0){
			return false;
		}
		return true;
	}
	
	public IProject[] getPreSelectedProjects(){
		return preSelectedProjects;
	}
	
	@Override
	public boolean canFinish() {
		// There must be projects selected
		if (!isProjectSelected()) {
			return false;
		}
		// There must be a tag
		if (!tagPage.isPageComplete()) {
			return false;
		}
		IWizardPage currentPage = getContainer().getCurrentPage();
		if (currentPage == validatePage)
			return false;
		
		// Force map comparison if option set by user
		if(currentPage == tagPage){
			if(tagPage.compareButtonSelected()){
				return false;
			}
		}
		return true;
	}

	public MapProject getMapProject(){
		return mapProject;
	}	
	public void broadcastMapProjectChange(MapProject m){
		mapProject = m;
		projectSelectionPage.updateMapProject(m);
		projectComparePage.updateMapProject(m);
		mapComparePage.updateMapProject(m);
	}
}
