/*******************************************************************************
 * Copyright (c) 2003, 2004 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;

public class WebServiceViewerSynchronization implements WebServiceManagerListener{
	
	public static final String ARE_THERE_WEBSERVICES = "areThereWebServices";

	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("Searching for web service capable projects...", 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() {
		String val = WebServiceUIPlugin.getDefault().getPluginPreferences().getString(WebServiceViewerSynchronization.ARE_THERE_WEBSERVICES);
		return Boolean.valueOf(val).booleanValue();
	}

	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);
		}

		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);
		}

		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);
		}

		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);
		}

		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.isDisposed()
								&& !contentProvider.projectListener.isListening())
							contentProvider.projectListener.startListening();
					}
				}
			}
			return Status.OK_STATUS;
		} 
	}


}
