/*******************************************************************************
 * Copyright (c) 2000, 2004 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.update.internal.ui.wizards;
import java.lang.reflect.*;
import java.net.*;
import java.util.*;

import org.eclipse.core.runtime.*;
import org.eclipse.core.runtime.jobs.*;
import org.eclipse.jface.dialogs.*;
import org.eclipse.jface.operation.*;
import org.eclipse.jface.wizard.*;
import org.eclipse.ui.*;
import org.eclipse.ui.progress.*;
import org.eclipse.update.configuration.*;
import org.eclipse.update.core.*;
import org.eclipse.update.core.model.*;
import org.eclipse.update.internal.core.*;
import org.eclipse.update.internal.operations.*;
import org.eclipse.update.internal.ui.*;
import org.eclipse.update.internal.ui.security.*;
import org.eclipse.update.operations.*;
import org.eclipse.update.search.*;


public class InstallWizard2
	extends Wizard
	implements IOperationListener, ISearchProvider {
	private ReviewPage reviewPage;
	private LicensePage licensePage;
	private OptionalFeaturesPage optionalFeaturesPage;
	private TargetPage targetPage;
	private IInstallConfiguration config;
	private int installCount = 0;
	private UpdateSearchRequest searchRequest;
	private ArrayList jobs;
	private boolean needsRestart;
	private static boolean isRunning;
	private IBatchOperation installOperation;
	private Job job;
	public static final Object jobFamily = new Object();
	private IJobChangeListener jobListener;
    private final boolean isUpdate;

	public InstallWizard2(UpdateSearchRequest searchRequest, ArrayList jobs, boolean isUpdate) {
        this.isUpdate = isUpdate;
        this.searchRequest = searchRequest;
        this.jobs = jobs;
        isRunning = true;
        setDialogSettings(UpdateUI.getDefault().getDialogSettings());
        setDefaultPageImageDescriptor(UpdateUIImages.DESC_UPDATE_WIZ);
        setForcePreviousAndNextButtons(true);
        setNeedsProgressMonitor(true);
        setWindowTitle(UpdateUI.getString("InstallWizard.wtitle")); //$NON-NLS-1$
	}
    
	public int getInstallCount() {
		return installCount;
	}
	public boolean isRestartNeeded() {
		return installCount > 0 && needsRestart; // or == selectedJobs.length
	}

	public boolean performCancel() {
		isRunning = false;
		if (targetPage != null)
			targetPage.removeAddedSites();
		return super.performCancel();
	}
	/**
	 * @see Wizard#performFinish()
	 */
	public boolean performFinish() {
		IInstallFeatureOperation[] selectedJobs = reviewPage.getSelectedJobs();
		
		// Check for duplication conflicts
		ArrayList conflicts = DuplicateConflictsValidator.computeDuplicateConflicts(selectedJobs, config);
		if (conflicts != null) {
			DuplicateConflictsDialog dialog = new DuplicateConflictsDialog(getShell(), conflicts);
			if (dialog.open() != 0)
				return false;
		}
		
		if (Platform.getJobManager().find(jobFamily).length > 0) {
			// another update/install job is running, need to wait to finish or cancel old job
			boolean proceed = MessageDialog.openQuestion(
					UpdateUI.getActiveWorkbenchShell(),
					UpdateUI.getString("InstallWizard.anotherJobTitle"),
					UpdateUI.getString("InstallWizard.anotherJob")); //$NON-NLS-1$
			if (!proceed)
				return false; // cancel this job, and let the old one go on
		}
		
		// set the install operation
		installOperation = getBatchInstallOperation(selectedJobs);
		if (installOperation != null)
			launchInBackground();
		return true;
	}

	public void addPages() {
		reviewPage = new ReviewPage(isUpdate, searchRequest, jobs);
		addPage(reviewPage);

		try {
//			config = UpdateUtils.createInstallConfiguration();
			config = SiteManager.getLocalSite().getCurrentConfiguration();
		} catch (CoreException e) {
			UpdateUI.logException(e);
		}

		licensePage = new LicensePage(true);
		addPage(licensePage);
		optionalFeaturesPage = new OptionalFeaturesPage(config);
		addPage(optionalFeaturesPage);
		targetPage = new TargetPage(config);
		addPage(targetPage);
	}


	private boolean isPageRequired(IWizardPage page) {
		if (page == null)
			return false;
			
		if (page.equals(licensePage)) {
			return OperationsManager.hasSelectedJobsWithLicenses(
				reviewPage.getSelectedJobs());
		}
		if (page.equals(optionalFeaturesPage)) {
			return OperationsManager.hasSelectedJobsWithOptionalFeatures(
				reviewPage.getSelectedJobs());
		}
		if (page.equals(targetPage)) {
			return reviewPage.getSelectedJobs().length > 0;
		}
		return true;
	}

	public IWizardPage getNextPage(IWizardPage page) {
		IWizardPage[] pages = getPages();
		boolean start = false;
		IWizardPage nextPage = null;

		if (page.equals(reviewPage)) {
			updateDynamicPages();
		}

		for (int i = 0; i < pages.length; i++) {
			if (pages[i].equals(page)) {
				start = true;
			} else if (start) {
				if (isPageRequired(pages[i])) {
					nextPage = pages[i];
					break;
				}
			}
		}
		return nextPage;
	}

	private void updateDynamicPages() {
		if (licensePage != null) {
			IInstallFeatureOperation[] licenseJobs =
				OperationsManager.getSelectedJobsWithLicenses(
					reviewPage.getSelectedJobs());
			licensePage.setJobs(licenseJobs);
		}
		if (optionalFeaturesPage != null) {
			IInstallFeatureOperation[] optionalJobs =
				OperationsManager.getSelectedJobsWithOptionalFeatures(
					reviewPage.getSelectedJobs());
			optionalFeaturesPage.setJobs(optionalJobs);
		}
		if (targetPage != null) {
			IInstallFeatureOperation[] installJobs =
				reviewPage.getSelectedJobs();
			targetPage.setJobs(installJobs);
		}
	}

	public boolean canFinish() {
		IWizardPage page = getContainer().getCurrentPage();
		return page.equals(targetPage) && page.isPageComplete();
	}

	private void preserveOriginatingURLs(
		IFeature feature,
		IFeatureReference[] optionalFeatures) {
		// walk the hierarchy and preserve the originating URL
		// for all the optional features that are not chosen to
		// be installed.
		URL url = feature.getSite().getURL();
		try {
			IIncludedFeatureReference[] irefs =
				feature.getIncludedFeatureReferences();
			for (int i = 0; i < irefs.length; i++) {
				IIncludedFeatureReference iref = irefs[i];
				boolean preserve = false;
				if (iref.isOptional()) {
					boolean onTheList = false;
					for (int j = 0; j < optionalFeatures.length; j++) {
						if (optionalFeatures[j].equals(iref)) {
							//was on the list
							onTheList = true;
							break;
						}
					}
					if (!onTheList)
						preserve = true;
				}
				if (preserve) {
					try {
						String id =
							iref.getVersionedIdentifier().getIdentifier();
						UpdateUI.setOriginatingURL(id, url);
					} catch (CoreException e) {
						// Silently ignore
					}
				} else {
					try {
						IFeature ifeature = iref.getFeature(null);
						preserveOriginatingURLs(ifeature, optionalFeatures);
					} catch (CoreException e) {
						// Silently ignore
					}
				}
			}
		} catch (CoreException e) {
			// Silently ignore
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.update.operations.IOperationListener#afterExecute(org.eclipse.update.operations.IOperation)
	 */
	public boolean afterExecute(IOperation operation, Object data) {
		if (!(operation instanceof IInstallFeatureOperation))
			return true;
		IInstallFeatureOperation job = (IInstallFeatureOperation) operation;
		IFeature oldFeature = job.getOldFeature();
		if (oldFeature == null && job.getOptionalFeatures() != null)
			preserveOriginatingURLs(
				job.getFeature(),
				job.getOptionalFeatures());

		installCount++;
		return true;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.update.operations.IOperationListener#beforeExecute(org.eclipse.update.operations.IOperation)
	 */
	public boolean beforeExecute(IOperation operation, Object data) {
		return true;
	}
	/* (non-Javadoc)
	 * @see org.eclipse.update.internal.ui.wizards.ISearchProvider2#getSearchRequest()
	 */
	public UpdateSearchRequest getSearchRequest() {
		return searchRequest;
	}

	public static synchronized boolean isRunning() {
		return isRunning || Platform.getJobManager().find(jobFamily).length > 0;
	}
	
	private IBatchOperation getBatchInstallOperation(final IInstallFeatureOperation[] selectedJobs) {
		final IVerificationListener verificationListener =new JarVerificationService(
				//InstallWizard.this.getShell());
				UpdateUI.getActiveWorkbenchShell());
		
		// setup jobs with the correct environment
		IInstallFeatureOperation[] operations =	new IInstallFeatureOperation[selectedJobs.length];
		for (int i = 0; i < selectedJobs.length; i++) {
			IInstallFeatureOperation job = selectedJobs[i];
			IFeature[] unconfiguredOptionalFeatures = null;
			IFeatureReference[] optionalFeatures = null;
			if (UpdateUtils.hasOptionalFeatures(job.getFeature())) {
				optionalFeatures = optionalFeaturesPage.getCheckedOptionalFeatures(job);
				unconfiguredOptionalFeatures = optionalFeaturesPage.getUnconfiguredOptionalFeatures(job, job.getTargetSite());
			}
			IInstallFeatureOperation op =
				OperationsManager
					.getOperationFactory()
					.createInstallOperation(
					job.getTargetSite(),
					job.getFeature(),
					optionalFeatures,
					unconfiguredOptionalFeatures,
					verificationListener);
			operations[i] = op;
		}
		return OperationsManager.getOperationFactory().createBatchInstallOperation(operations);
	}



	private void launchInBackground() {
		// Downloads the feature content in the background.
		// The job listener will then install the feature when download is finished.
		
		// TODO: should we cancel existing jobs?
		if (jobListener != null)
			Platform.getJobManager().removeJobChangeListener(jobListener);
		if (job != null)
			Platform.getJobManager().cancel(job);
		jobListener = new UpdateJobChangeListener();
		Platform.getJobManager().addJobChangeListener(jobListener);
		
		job = new Job(UpdateUI.getString("InstallWizard.jobName")) { //$NON-NLS-1$	
			public IStatus run(IProgressMonitor monitor) {
				if (download(monitor))
					return Status.OK_STATUS;
				else {
					isRunning = false;
					return Status.CANCEL_STATUS;
				}
			}
			public boolean belongsTo(Object family) {
				return InstallWizard2.jobFamily == family;
			}
		};

		job.setUser(true);
		job.setPriority(Job.INTERACTIVE);
//		if (wait) {
//			progressService.showInDialog(workbench.getActiveWorkbenchWindow().getShell(), job); 
//		}
		job.schedule();
	}
	
	private void install(IProgressMonitor monitor) {
		// Installs the (already downloaded) features and prompts for restart
		try {
			needsRestart = installOperation.execute(monitor, InstallWizard2.this);
			UpdateUI.getStandardDisplay().asyncExec(new Runnable() {
				public void run() {
					UpdateUI.requestRestart(InstallWizard2.this.isRestartNeeded());
				}
			});
		} catch (final InvocationTargetException e) {
			final Throwable targetException = e.getTargetException();
			if (!(targetException instanceof InstallAbortedException)){
				UpdateUI.getStandardDisplay().syncExec(new Runnable() {
					public void run() {
						UpdateUI.logException(targetException);
					}
				});
			}
		} catch (CoreException e) {
		} finally {
			isRunning = false;
		}
	}
	
	private boolean download(final IProgressMonitor monitor) {
		// Downloads the feature content.
		// This method is called from a background job.
		// If download fails, the user is prompted to retry.
		try {
			IFeatureOperation[] ops = installOperation.getOperations();
			monitor.beginTask(UpdateUI.getString("InstallWizard.download"), 3*ops.length);
			for (int i=0; i<ops.length; i++) {
				IInstallFeatureOperation op = (IInstallFeatureOperation)ops[i];
				SubProgressMonitor subMonitor = new SubProgressMonitor(monitor, 3);
				try {
					UpdateUtils.downloadFeatureContent(op.getTargetSite(), op.getFeature(), op.getOptionalFeatures(), subMonitor);
				} catch (final CoreException e) {
					if(e instanceof FeatureDownloadException){
						boolean retry = retryDownload((FeatureDownloadException)e);
						if (retry) {
							// redownload current feature
							i--;
							continue;
						}
					} else {
						UpdateCore.log(e);
					}
					return false;
				}
			}
			return true;
		} finally {
			monitor.done();
		}
	}
	
	private boolean retryDownload(final FeatureDownloadException e) {

		final boolean retry[] = new boolean[1];
		UpdateUI.getStandardDisplay().syncExec(new Runnable() {
			public void run() {
				retry[0] =	MessageDialog.openQuestion(
					UpdateUI.getActiveWorkbenchShell(),
					UpdateUI.getString("InstallWizard.retryTitle"), //$NON-NLS-1$
					e.getMessage()+"\n" //$NON-NLS-1$
						+ UpdateUI.getString("InstallWizard.retry")); //$NON-NLS-1$
			}
		});
		return retry[0];
	}
    

    private class UpdateJobChangeListener extends JobChangeAdapter {
        public void done(final IJobChangeEvent event) {
            // the job listener is triggered when the download job is done, and it proceeds
            // with the actual install
            if (event.getJob() == InstallWizard2.this.job && event.getResult() == Status.OK_STATUS) {
                Platform.getJobManager().removeJobChangeListener(this);
                Platform.getJobManager().cancel(job);
                
                final IProgressService progressService= PlatformUI.getWorkbench().getProgressService();
                UpdateUI.getStandardDisplay().asyncExec(new Runnable() {
                    public void run() {
                        try {
                            progressService.busyCursorWhile( new IRunnableWithProgress() {
                                public void run(final IProgressMonitor monitor){
                                    install(monitor);
                                }
                            });
                        } catch (InvocationTargetException e) {
                            UpdateUI.logException(e);
                        } catch (InterruptedException e) {
                            UpdateUI.logException(e, false);
                        }
                    }
                }); 
            } else if (event.getJob() == InstallWizard2.this.job && event.getResult() != Status.OK_STATUS) {
                isRunning = false;
                Platform.getJobManager().removeJobChangeListener(this);
                Platform.getJobManager().cancel(job);
                UpdateUI.getStandardDisplay().syncExec(new Runnable() {
                    public void run() {
                        UpdateUI.log(event.getResult(), true);
                    }
                });
            }
        }
    }

}
