/*******************************************************************************
 * Copyright (c) 2003, 2007 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.jst.j2ee.internal.webservice;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jst.j2ee.internal.webservice.helper.WebServiceEvent;
import org.eclipse.jst.j2ee.internal.webservice.helper.WebServiceManagerListener;
import org.eclipse.jst.j2ee.internal.webservice.helper.WebServicesManager;
import org.eclipse.jst.j2ee.internal.webservice.plugin.WebServiceUIPlugin;
import org.eclipse.jst.j2ee.navigator.internal.IJ2EENavigatorConstants;
import org.eclipse.ui.progress.UIJob;
import org.eclipse.wst.common.internal.emfworkbench.integration.DynamicAdapterFactory;
import org.eclipse.wst.common.project.facet.core.internal.FacetedProjectPropertyTester;
import org.eclipse.wst.project.facet.ProductManager;
import org.eclipse.jst.j2ee.internal.webservice.WebServiceUIResourceHandler;

public class WebServiceViewerSynchronization implements WebServiceManagerListener{
	
	public static final String ARE_THERE_WEBSERVICES = "areThereWebServices"; //$NON-NLS-1$

	private WebServicesManager webServicesManager = null; 
	
    private static final String PROJECT_FACET = "projectFacet"; //$NON-NLS-1$     
    
    /* The facets are duplicated here to avoid loading plugins just for constants */
    /* package */ static final String EAR_FACET = "jst.ear"; //$NON-NLS-1$ 
    /* package */ static final String APPCLIENT_FACET = "jst.appclient"; //$NON-NLS-1$ 
    /* package */ static final String WEB_FACET = "jst.web"; //$NON-NLS-1$ 
    /* package */ static final String EJB_FACET = "jst.ejb"; //$NON-NLS-1$ 
    /* package */ static final String UTILITY_FACET = "jst.utility"; //$NON-NLS-1$ 
    /* package */ static final String CONNECTOR_FACET = "jst.connector"; //$NON-NLS-1$ 
    /* package */ static final String STATIC_WEB_FACET = "wst.web"; //$NON-NLS-1$ 
    
    private static final FacetedProjectPropertyTester facetPropertyTester = new FacetedProjectPropertyTester();

    
    private WebServicesNavigatorContentProvider contentProvider;

	private Job indexJob = new WebServiceIndexJob();
	private Job updateJob = new UpdateWebServicesNodeUIJob(); 
	private Job removeJob = new RemoveWebServicesNodeUIJob(); 

	private boolean navigatorGroupAdded = false;
	boolean indexJobScheduled = false;
	
	private boolean initialized = false;
	
	public WebServiceViewerSynchronization(WebServicesNavigatorContentProvider provider) {
		contentProvider = provider; 
	}
	

	public void start() {

		try { 
			
			getWebServicesManager().addListener(this);
			
			// create the default synchronizer for any web service editor to use with view due
			// to the usage of seperate edit models.
			WebServicesNavigatorSynchronizer.createInstance(
							new DynamicAdapterFactory(IJ2EENavigatorConstants.VIEWER_ID), contentProvider);
		} finally { 
			initialized = true;
		} 
	}
	 
	public void stop() { 
		if(initialized) {
			getWebServicesManager().removeListener(this);
			// dispose current instance of web service editor/explorer synchronizer
			WebServicesNavigatorSynchronizer.disposeInstance();
		}
	}
	
	public void webServiceManagerChanged(WebServiceEvent anEvent) {
		
		switch (anEvent.getEventType()) {
			case WebServiceEvent.REFRESH:

				if(!hasNavigatorGroupBeenAdded()) {
					if(!hasIndexJobBeenScheduled()){
						indexJob.schedule();
					}
					if(!hasNavigatorGroupBeenAdded())
						addWebServiceNode();
				} else {
					updateJob.schedule();
				}
				break;
			case WebServiceEvent.REMOVE:
				if(hasNavigatorGroupBeenAdded())
					removeJob.schedule();
		}
	}


	void addWebServiceNode() {
		new AddWebServicesNodeUIJob().schedule();
	}


	public void startIndexJob() {
		indexJob.schedule();
	} 
	
	/**
	 * Employ a Test-And-Set (TST) primitive to ensure the Job is only scheduled once per load.
	 * 
	 * @return True if the the index job has been scheduled. The value of indexJobSchedule will
	 *         _always_ be true after this method executes, so if false is returned, the job must be
	 *         scheduled by the caller.
	 */
	/* package */ synchronized boolean hasIndexJobBeenScheduled() {
		if (!indexJobScheduled) {
			indexJobScheduled = true;
			return false;
		}
		return true;
	}

	/**
	 * Multiple threads access this boolean flag, so we synchronize it to ensure that its value is
	 * consistent across different threads.
	 * 
	 * @return True if the WebServicesNavigatorGroup has already been processed and added to the
	 *         tree.
	 */
	/* package */ synchronized boolean hasNavigatorGroupBeenAdded() {
		return navigatorGroupAdded;
	} 
	
	/* package */ synchronized void setNavigatorGroupAdded(boolean hasBeenAdded) {
		navigatorGroupAdded = hasBeenAdded;
	}

	private WebServicesManager getWebServicesManager() {
		if (webServicesManager == null)
			webServicesManager = WebServicesManager.getInstance();
		return webServicesManager;
	}
	
	private boolean indexWebServices(IProgressMonitor monitor) {
		boolean hasChildren = false;
		if (!monitor.isCanceled()) {
			try {
				hasChildren |= getWebServicesManager().getWorkspace13ServiceRefs().size() > 0;
			} catch (RuntimeException e) { 
				WebServiceUIPlugin.logError(0, e.getMessage(), e);
			}
		} else {
			return hasChildren;
		}
		monitor.worked(1);

		if (!monitor.isCanceled()) {
			try {
				hasChildren |= getWebServicesManager().getWorkspace14ServiceRefs().size() > 0;
			} catch (RuntimeException e) { 
				WebServiceUIPlugin.logError(0, e.getMessage(), e);
			}
		} else {
			return hasChildren;
		}
		monitor.worked(1);

		if (!monitor.isCanceled()) {
			try {
				hasChildren |= getWebServicesManager().getInternalWSDLServices().size() > 0;
			} catch (RuntimeException e) { 
				WebServiceUIPlugin.logError(0, e.getMessage(), e);
			}
		} else {
			return hasChildren;
		}
		monitor.worked(1);

		if (!monitor.isCanceled()) {
			try {
				hasChildren |= getWebServicesManager().getExternalWSDLServices().size() > 0;
			} catch (RuntimeException e) { 
				WebServiceUIPlugin.logError(0, e.getMessage(), e);
			}
		} else {
			return hasChildren;
		}
		monitor.worked(1);
		return hasChildren;
	}
	
	/* package */ static boolean hasFacet(Object element, String facet) {
		return facetPropertyTester.test(element, PROJECT_FACET, new Object[] {}, facet);
	}
	
	/* package */ boolean webServiceProjectsExist(IProgressMonitor monitor) { 	
		boolean ret = false;
		IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
		
		monitor.beginTask(WebServiceUIResourceHandler.WebServiceViewerSynchronization_Searching_for_web_service_capable_p_, projects.length);
		for (int i = 0; i < projects.length; i++) {
			 if(isInteresting(projects[i])){
				 ret = true;
				 break;
			 }	 
		}
		monitor.worked(1);
		return ret;
	}

	public static void setAreThereWebServices(boolean isThereWebServices) {
		// set the value of WebServiceViewerSynchronization.ARE_THERE_WEBSERVICES so that we do not index in future
		WebServiceUIPlugin.getDefault().getPluginPreferences().setValue(ARE_THERE_WEBSERVICES, Boolean.toString(isThereWebServices));
		WebServiceUIPlugin.getDefault().savePluginPreferences();
	}
	
	public static boolean areThereWebServices() {
		if (ProductManager.shouldUseViewerSyncForWebservices()) {
			String val = WebServiceUIPlugin.getDefault().getPluginPreferences().getString(WebServiceViewerSynchronization.ARE_THERE_WEBSERVICES);
			return Boolean.parseBoolean(val);
		}
		return false;
	}

	public static boolean isThereWebServicesPreferenceSet() {
		return WebServiceUIPlugin.getDefault().getPluginPreferences().contains(WebServiceViewerSynchronization.ARE_THERE_WEBSERVICES);
	}


	/* package */ public static boolean isInteresting(IProject project) {
		return hasFacet(project, WEB_FACET) || 
			hasFacet(project, EJB_FACET) || 
			hasFacet(project, APPCLIENT_FACET);
	}

	public class WebServiceIndexJob extends Job {
	
		public WebServiceIndexJob() {
			super(WebServiceUIResourceHandler.WS_NAV_JOB0);
			// [204833]
			//setRule(new NonConflictingRule());
			setRule(ResourcesPlugin.getWorkspace().getRoot());
			setSystem(true);
		}

		@Override
		protected IStatus run(IProgressMonitor monitor) {
			monitor.beginTask(WebServiceUIResourceHandler.WS_NAV_JOB1, 5);
			
			boolean isThereWebServices = false;
			if (webServiceProjectsExist(monitor)) {
				isThereWebServices =  indexWebServices(monitor);
				if( isThereWebServices ){
					setAreThereWebServices(isThereWebServices);		
				}
			}else{
				setAreThereWebServices(false);
			}
			if(!hasNavigatorGroupBeenAdded()){
				if(isThereWebServices)
					addWebServiceNode();
			}

			monitor.done();
			
			return Status.OK_STATUS;
		}
	}

	public class AddWebServicesNodeUIJob extends UIJob {


		public AddWebServicesNodeUIJob() {
			super(WebServiceUIResourceHandler.WS_NAV_JOB2);
		}

		@Override
		public IStatus runInUIThread(IProgressMonitor monitor) {

			TreeViewer viewer = contentProvider.getViewer();
			if(!viewer.getControl().isDisposed()) {
				viewer.add(viewer.getInput(), contentProvider.getNavigatorGroup());
			}
			setNavigatorGroupAdded(true);
			return Status.OK_STATUS;
		} 
	}

	public class UpdateWebServicesNodeUIJob extends UIJob {
 
		public UpdateWebServicesNodeUIJob () {
			super(WebServiceUIResourceHandler.WS_NAV_JOB3);
		}

		@Override
		public IStatus runInUIThread(IProgressMonitor monitor) {
			TreeViewer viewer = contentProvider.getViewer();

			if(!viewer.getControl().isDisposed()) {
				if(hasNavigatorGroupBeenAdded())
					contentProvider.getViewer().refresh(contentProvider.getNavigatorGroup());
				else {
					viewer.add(viewer.getInput(), contentProvider.getNavigatorGroup());
					setNavigatorGroupAdded(true);
				}
			}
			return Status.OK_STATUS;
		} 
	}
	 
	public class RemoveWebServicesNodeUIJob extends UIJob { 

		public RemoveWebServicesNodeUIJob() {
			super(WebServiceUIResourceHandler.WS_NAV_JOB4);
			// [204833]
			setRule(ResourcesPlugin.getWorkspace().getRoot());
			setSystem(true);
		}

		@Override
		public IStatus runInUIThread(IProgressMonitor monitor) { 

			monitor.beginTask(WebServiceUIResourceHandler.WS_NAV_JOB5, 4);

			TreeViewer viewer = contentProvider.getViewer();

			if(!viewer.getControl().isDisposed()) {
				if(hasNavigatorGroupBeenAdded()){
					if (indexWebServices(monitor)) {
						viewer.refresh(contentProvider.getNavigatorGroup());
						setAreThereWebServices(true);
					} else {
						viewer.remove(contentProvider.getNavigatorGroup());
						setNavigatorGroupAdded(false);
						setAreThereWebServices(false);
						if(contentProvider.projectListener != null && !contentProvider.projectListener.isDisposed()
								&& !contentProvider.projectListener.isListening())
							contentProvider.projectListener.startListening();
					}
				}
			}
			return Status.OK_STATUS;
		} 
	}


}
