/*******************************************************************************
 * 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.common;


import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.emf.common.util.URI;
import org.eclipse.jem.util.emf.workbench.ProjectUtilities;
import org.eclipse.jst.j2ee.application.internal.operations.ClassPathSelection;
import org.eclipse.jst.j2ee.application.internal.operations.ClasspathElement;
import org.eclipse.jst.j2ee.classpathdep.ClasspathDependencyUtil;
import org.eclipse.jst.j2ee.commonarchivecore.internal.helpers.ArchiveManifest;
import org.eclipse.jst.j2ee.componentcore.J2EEModuleVirtualComponent;
import org.eclipse.jst.j2ee.internal.J2EEConstants;
import org.eclipse.jst.j2ee.internal.plugin.J2EEPlugin;
import org.eclipse.jst.j2ee.internal.project.J2EEProjectUtilities;
import org.eclipse.jst.j2ee.project.EarUtilities;
import org.eclipse.jst.j2ee.project.JavaEEProjectUtilities;
import org.eclipse.wst.common.componentcore.ComponentCore;
import org.eclipse.wst.common.componentcore.UnresolveableURIException;
import org.eclipse.wst.common.componentcore.internal.ModuleStructuralModel;
import org.eclipse.wst.common.componentcore.internal.StructureEdit;
import org.eclipse.wst.common.componentcore.internal.impl.ModuleURIUtil;
import org.eclipse.wst.common.componentcore.internal.util.ComponentUtilities;
import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
import org.eclipse.wst.common.componentcore.resources.IVirtualReference;
import org.eclipse.wst.common.internal.emfworkbench.validateedit.ResourceStateInputProvider;
import org.eclipse.wst.common.internal.emfworkbench.validateedit.ResourceStateValidator;
import org.eclipse.wst.common.internal.emfworkbench.validateedit.ResourceStateValidatorImpl;
import org.eclipse.wst.common.internal.emfworkbench.validateedit.ResourceStateValidatorPresenter;

public class ClasspathModel implements ResourceStateInputProvider, ResourceStateValidator {

	protected IProject project;
	protected IVirtualComponent selectedEARComponent;
	protected IVirtualComponent component;
	protected IVirtualComponent[] availableEARComponents = null;
	protected ClassPathSelection classPathSelection;
	protected List listeners;
	protected List nonResourceFiles;
	protected ResourceStateValidator stateValidator;
	protected ArchiveManifest manifest;
	public static String NO_EAR_MESSAGE = CommonEditResourceHandler.getString("NO_EAR_JARDEP_FOR_MOD_UI_"); //$NON-NLS-1$
	protected List targetWLPRefComponentList;
	protected boolean isWLPModel = false;
	protected ClassPathSelection classPathWLPSelection;

	protected Comparator comparator = new Comparator() {
		public int compare(Object o1, Object o2) {
			IVirtualComponent e1 = (IVirtualComponent) o1;
			IVirtualComponent e2 = (IVirtualComponent) o2;
			return e1.getProject().getName().compareTo(e2.getProject().getName());
		}
	};

	public ClasspathModel(ArchiveManifest initialManifest) {
		this(initialManifest, false);
	}
	
	public ClasspathModel(ArchiveManifest initialManifest, boolean isWLPModel) {
		super();
		manifest = initialManifest;
		this.isWLPModel = isWLPModel;
	}
	
	public IProject getProject() {
		return project;
	}

	public void setProject(IProject project) {
		this.project = project;
		initializeComponent();
		getAvailableEARComponents();
	}

	private void initializeComponent() {
		setComponent(ComponentCore.createComponent(getProject()));
	}

	protected IVirtualComponent[] refreshAvailableEARs() {
		if (component != null) {
			IProject[] earProjects = EarUtilities.getReferencingEARProjects(getComponent().getProject());
			availableEARComponents = ComponentUtilities.getComponents(earProjects);
			if (availableEARComponents != null && availableEARComponents.length > 0) {
				Arrays.sort(availableEARComponents, comparator);
				if (selectedEARComponent == null || !Arrays.asList(availableEARComponents).contains(selectedEARComponent)) {
					if (availableEARComponents.length > 0)
						selectedEARComponent = availableEARComponents[0];
					else
						selectedEARComponent = null;
				}
			}
		}
		return availableEARComponents;
	}

	public IVirtualComponent[] getAvailableEARComponents() {
		if (availableEARComponents == null)
			refreshAvailableEARs();
		return availableEARComponents;
	}

	public IVirtualComponent getSelectedEARComponent() {
		return selectedEARComponent;
	}

	public void setSelectedEARComponent(IVirtualComponent component) {
		selectedEARComponent = component;
		fireNotification(new ClasspathModelEvent(ClasspathModelEvent.EAR_PROJECT_CHANGED));
	}

	public String getArchiveURI() {
		if (selectedEARComponent != null) {
			IVirtualReference [] refs = selectedEARComponent.getReferences();
			IVirtualComponent moduleComp = getComponent();
			for(int i=0; i<refs.length; i++){
				if(refs[i].getReferencedComponent().equals(moduleComp)){
					return refs[i].getArchiveName();
				}
			}
		}
		return null;
	}

	protected void initializeSelection(ArchiveManifest existing) {
			if (!JavaEEProjectUtilities.isEARProject(getProject())) {
				if (getProject() != null) {
					if(existing != null){
						manifest = existing;
					}
				}
				if( existing == null )
					createClassPathSelection();
				else{
					createClassPathSelection(manifest);
				}
			}
	}

	protected void createClassPathSelection() {
		if (getComponent() != null && selectedEARComponent != null ) {
			classPathSelection = new ClassPathSelection(getComponent(), selectedEARComponent);
		} else if (selectedEARComponent == null) {
			classPathSelection = new ClassPathSelection(getComponent());
		} else {
			classPathSelection = null;
		}
	}
	
	protected void createClassPathSelection(ArchiveManifest manifest) {
		if (getComponent() != null && selectedEARComponent != null ) {
			classPathSelection = new ClassPathSelection(getComponent(), selectedEARComponent, manifest);
		} else if (selectedEARComponent == null) {
			classPathSelection = new ClassPathSelection(getComponent(), manifest);
		} else {
			classPathSelection = null;
		}
	}
	

	public void dispose() {
	}

	public ClassPathSelection getClassPathSelection() {
		if (classPathSelection == null)
			initializeSelection(null);
		return classPathSelection;
	}

	public void resetClassPathSelection(ArchiveManifest mf) {
		initializeSelection(mf);
		fireNotification(new ClasspathModelEvent(ClasspathModelEvent.CLASS_PATH_RESET));
	}

	public void resetClassPathSelection() {
		resetClassPathSelection(null);
	}
	
	public void resetClassPathSelectionForWLPs() {
		classPathWLPSelection = null;
	}

	public void addListener(ClasspathModelListener listener) {
		if (listeners == null)
			listeners = new ArrayList();

		listeners.add(listener);
	}

	public void removeListener(ClasspathModelListener listener) {
		if (listeners != null)
			listeners.remove(listener);
	}

	public void fireNotification(ClasspathModelEvent evt) {
		if (listeners == null)
			return;

		for (int i = 0; i < listeners.size(); i++) {
			ClasspathModelListener listener = (ClasspathModelListener) listeners.get(i);
			listener.modelChanged(evt);
		}
	}

	/**
	 * Sets the isSelected for the classpath element and sends out a notification of type
	 * {@link ClasspathModelEvent#CLASS_PATH_CHANGED}
	 */
	public void setSelection(ClasspathElement element, boolean selected) {
		element.setSelected(selected);
		if (!isWLPModel()) {
			updateManifestClasspath();
		} else {
			// at least fire the change event
			fireNotification(new ClasspathModelEvent(ClasspathModelEvent.CLASS_PATH_CHANGED));
		}
	}

	/**
	 * Select or deselect all and notify
	 */
	public void setAllClasspathElementsSelected(boolean selected) {
		ClassPathSelection s = getClassPathSelection();
		if (s != null) {
			s.setAllSelected(selected);
			updateManifestClasspath();
		}
	}

	/**
	 * Select or deselect all and notify
	 */
	public void setAllClasspathElementsSelected(List elements, boolean selected) {
		ClassPathSelection s = getClassPathSelection();
		if (s != null) {
			s.setAllSelected(elements, selected);
			updateManifestClasspath();
		}
	}

	/**
	 * Updates the manifest Class-Path:, and sends out a notification of type
	 * {@link ClasspathModelEvent#CLASS_PATH_CHANGED}
	 */
	public void updateManifestClasspath() {
		if (classPathSelection != null && classPathSelection.isModified()) {
			manifest.setClassPath(classPathSelection.toString());
			fireNotification(new ClasspathModelEvent(ClasspathModelEvent.CLASS_PATH_CHANGED));
		}
	}

	/**
	 * Updates the manifest Main-Class:, and sends out a notification of type
	 * {@link ClasspathModelEvent#MAIN_CLASS_CHANGED}
	 */
	public void updateMainClass(String mainClass) {
		manifest.setMainClass(mainClass);
		fireNotification(new ClasspathModelEvent(ClasspathModelEvent.MAIN_CLASS_CHANGED));
	}

	/**
	 * Updates the manifest Main-Class:, and sends out a notification of type
	 * {@link ClasspathModelEvent#MAIN_CLASS_CHANGED}
	 */
	public void updateImplVersion(String implVersion) {
		manifest.setImplemenationVersion(implVersion);
		fireNotification(new ClasspathModelEvent(ClasspathModelEvent.IMPL_VERSION_CHANGED));
	}

	public void fireSavedEvent() {
		fireNotification(new ClasspathModelEvent(ClasspathModelEvent.MODEL_SAVED));
	}

	/**
	 * Sets the manifest without touching the archive, or notifying
	 */
	public void primSetManifest(ArchiveManifest mf) {
		manifest = mf;
	}

	/**
	 * Sets the manfest on the archive, updates the classpath selection, and notifies
	 */
	public void setManifest(ArchiveManifest newManifest) {
		try {
			J2EEProjectUtilities.writeManifest(getProject(), newManifest);
		} catch (IOException e) {
			J2EEPlugin.logError(e);
		}
		classPathSelection = null;
		getClassPathSelection(); // Ensure the selection is initialized.
		fireNotification(new ClasspathModelEvent(ClasspathModelEvent.MANIFEST_CHANGED));
	}
	
	public void forceUpdateClasspath(ArchiveManifest newManifest) {
		primSetManifest(newManifest);
		classPathSelection = null;
		initializeSelection(newManifest);
		fireNotification(new ClasspathModelEvent(ClasspathModelEvent.MANIFEST_CHANGED));		
	}	

	public void selectEAR(int index) {
		selectedEARComponent = availableEARComponents[index];
		initializeSelection(null);
		fireNotification(new ClasspathModelEvent(ClasspathModelEvent.EAR_PROJECT_CHANGED));
	}

	public void moveUp(List toMoveUp) {
		getClassPathSelection().moveUp(toMoveUp);
		updateManifestClasspath();
	}

	public void moveDown(List toMoveDown) {
		getClassPathSelection().moveDown(toMoveDown);
		updateManifestClasspath();
	}

	public void refresh() {
		ArchiveManifest mf = null;
		if (getComponent() != null)
			mf = J2EEProjectUtilities.readManifest(getProject());
		refreshAvailableEARs();
		resetClassPathSelection(mf);
	}

	/**
	 * @see com.ibm.etools.emf.workbench.ResourceStateInputProvider#cacheNonResourceValidateState(List)
	 */
	public void cacheNonResourceValidateState(List roNonResourceFiles) {
	}

	/**
	 * @see com.ibm.etools.emf.workbench.ResourceStateInputProvider#getNonResourceFiles()
	 */
	public List getNonResourceFiles() {
		if (nonResourceFiles == null)
			initNonResourceFiles();
		return nonResourceFiles;
	}

	protected void initNonResourceFiles() {
		// Might be opened from a JAR
		if (getComponent() == null || getComponent().isBinary()){
			return;
		} 
		nonResourceFiles = new ArrayList(1);
		if(isWLPModel){
			IFile dotProject = getComponent().getProject().getFile(ProjectUtilities.DOT_PROJECT);
			if(dotProject != null){
				nonResourceFiles.add(dotProject);
			}
		} else {
			IFile mf = J2EEProjectUtilities.getManifestFile(getComponent().getProject());
			if (mf != null){
				nonResourceFiles.add(mf);
			}
		}
	}

	/**
	 * @see com.ibm.etools.emf.workbench.ResourceStateInputProvider#getNonResourceInconsistentFiles()
	 */
	public List getNonResourceInconsistentFiles() {
		return null;
	}

	/**
	 * @see com.ibm.etools.emf.workbench.ResourceStateInputProvider#isDirty()
	 */
	public boolean isDirty() {
		ClassPathSelection selection = getClassPathSelection();
		if (selection == null)
			return false;
		return selection.isModified();
	}


	/**
	 * Return a list of all the files that will get modified as a result of running this operation;
	 * used for validateEdit
	 */
	public Set getAffectedFiles() {
		Set result = new HashSet();
		IFile aFile = J2EEProjectUtilities.getManifestFile(getComponent().getProject());
		if (aFile != null && aFile.exists())
			result.add(aFile);
		result.addAll(ProjectUtilities.getFilesAffectedByClasspathChange(getComponent().getProject()));
		return result;
	}

	/**
	 * @see com.ibm.etools.emf.workbench.ResourceStateInputProvider#getResources()
	 */
	public List getResources() {
		if(isWLPModel){
			StructureEdit sEdit = null;
			try {
				sEdit = StructureEdit.getStructureEditForWrite(project);
				ModuleStructuralModel structuralModel = sEdit.getModuleStructuralModel();
				List resources = new ArrayList();
				resources.addAll(structuralModel.getResources());
				return resources;
			} catch(Exception e){
				J2EEPlugin.logError(e);
				return Collections.EMPTY_LIST;	
			}
			finally {
				if (sEdit !=null){
					sEdit.dispose();
				}
			}
		}
		return Collections.EMPTY_LIST;
	}

	public boolean selectDependencyIfNecessary(IProject referencedProject) {
		getClassPathSelection();
		if (classPathSelection == null || classPathSelection.hasDirectOrIndirectDependencyTo(referencedProject))
			return false;

		ClasspathElement element = classPathSelection.getClasspathElement(referencedProject);
		if (element != null) {
			setSelection(element, true);
			return true;
		}
		return false;
	}

	public boolean selectDependencyIfNecessary(String jarName) {
		getClassPathSelection();
		if (classPathSelection == null || classPathSelection.hasDirectOrIndirectDependencyTo(jarName))
			return false;

		ClasspathElement element = classPathSelection.getClasspathElement(jarName);
		if (element != null) {
			setSelection(element, true);
			return true;
		}
		return false;
	}

	public void removeDependency(String jarName) {
		getClassPathSelection();
		if (classPathSelection == null)
			return;

		ClasspathElement element = classPathSelection.getClasspathElement(jarName);
		if (element != null && element.isValid())
			setSelection(element, false);
	}

	public void removeDependency(IProject referencedProject) {
		getClassPathSelection();
		if (classPathSelection == null)
			return;

		ClasspathElement element = classPathSelection.getClasspathElement(referencedProject);
		if (element != null && element.isValid())
			setSelection(element, false);
	}

	public void selectFilterLevel(int filterLevel) {
		getClassPathSelection();
		if (classPathSelection != null)
			classPathSelection.selectFilterLevel(filterLevel);
		updateManifestClasspath();
	}

	/**
	 * Gets the stateValidator.
	 * 
	 * @return Returns a ResourceStateValidator
	 */
	public ResourceStateValidator getStateValidator() {
		if (stateValidator == null)
			stateValidator = createStateValidator();
		return stateValidator;
	}

	/**
	 * Method createStateValidator.
	 * 
	 * @return ResourceStateValidator
	 */
	private ResourceStateValidator createStateValidator() {
		return new ResourceStateValidatorImpl(this);
	}

	/**
	 * @see ResourceStateValidator#checkActivation(ResourceStateValidatorPresenter)
	 */
	public void checkActivation(ResourceStateValidatorPresenter presenter) throws CoreException {
		getStateValidator().checkActivation(presenter);
	}

	/**
	 * @see ResourceStateValidator#lostActivation(ResourceStateValidatorPresenter)
	 */
	public void lostActivation(ResourceStateValidatorPresenter presenter) throws CoreException {
		getStateValidator().lostActivation(presenter);
	}

	/**
	 * @see ResourceStateValidator#validateState(ResourceStateValidatorPresenter)
	 */
	public IStatus validateState(ResourceStateValidatorPresenter presenter) throws CoreException {
		return getStateValidator().validateState(presenter);
	}

	/**
	 * @see ResourceStateValidator#checkSave(ResourceStateValidatorPresenter)
	 */
	public boolean checkSave(ResourceStateValidatorPresenter presenter) throws CoreException {
		return getStateValidator().checkSave(presenter);
	}

	/**
	 * @see ResourceStateValidator#checkReadOnly()
	 */
	public boolean checkReadOnly() {
		return getStateValidator().checkReadOnly();
	}

	public IVirtualComponent getComponent() {
		return component;
	}

	public void setComponent(IVirtualComponent component) {
		this.component = component;
	}

	public ClassPathSelection getClassPathSelectionForWLPs() {
		if (classPathWLPSelection == null)
			initializeSelectionForWLPs();
		return classPathWLPSelection;
	}

	//copied from WebArtifactEdit
	private static IPath WEBLIB =  new Path(J2EEConstants.WEB_INF_LIB).makeAbsolute();
	private static IPath WEBINF_CLASSES =  new Path(J2EEConstants.WEB_INF_CLASSES).makeAbsolute();
	private static IVirtualReference[] getLibModules(IProject project) {
		List result = new ArrayList();
		IVirtualComponent comp = ComponentCore.createComponent(project);
		IVirtualReference[] refComponents = null;
		if (!comp.isBinary())
			refComponents = ((J2EEModuleVirtualComponent)comp).getNonManifestReferences();
		else
			refComponents = comp.getReferences();
		// Check the deployed path to make sure it has a lib parent folder and matchs the web.xml
		// base path
		for (int i = 0; i < refComponents.length; i++) {
			if (refComponents[i].getRuntimePath().equals(WEBLIB))
				result.add(refComponents[i]);
		}

		return (IVirtualReference[]) result.toArray(new IVirtualReference[result.size()]);
	}
	
	private void initializeSelectionForWLPs() {
		classPathWLPSelection = new ClassPathSelection();
		classPathWLPSelection.setFilterLevel(ClassPathSelection.FILTER_NONE);
		//this is the set of all projects that are already mapped as web library projects
		HashSet existingWebLibProjects = new HashSet();
		List otherExistingWebLibRefs = new ArrayList();
		IVirtualReference [] libModules = getLibModules(component.getProject());
		for(int i=0;i<libModules.length; i++){
			IVirtualComponent comp = libModules[i].getReferencedComponent();
			if(comp != null && comp.exists()){
				if(comp.isBinary()){
					otherExistingWebLibRefs.add(libModules[i]);
				} else {
					IProject p = comp.getProject();
					if(p != null && p.exists()){
						existingWebLibProjects.add(p);
					}
				}
			}
		}
		
		//this is the list of all projects that should show up in the list
		HashSet possibleWebLibs = new HashSet();
		try{
			List javaProjects = J2EEProjectUtilities.getAllJavaNonFlexProjects();
			possibleWebLibs.addAll(javaProjects);
		} catch(CoreException e){
			J2EEPlugin.logError(e);
		}
		IProject[] utilityProjects = J2EEProjectUtilities.getAllProjectsInWorkspaceOfType(J2EEProjectUtilities.UTILITY);
		possibleWebLibs.addAll(Arrays.asList(utilityProjects));
		IProject[] ejbProjects = J2EEProjectUtilities.getAllProjectsInWorkspaceOfType(J2EEProjectUtilities.EJB);
		possibleWebLibs.addAll(Arrays.asList(ejbProjects));
		
		Map pathToComp = new HashMap();
		
		//first handle the projects case
		for(Iterator iterator = possibleWebLibs.iterator(); iterator.hasNext();){
			IProject possibleWebLib = (IProject)iterator.next();
			if(possibleWebLib.getName().startsWith(".")){ //$NON-NLS-1$
				continue;
			}
			boolean isExistingWebLib = existingWebLibProjects.contains(possibleWebLib);
			classPathWLPSelection.createProjectElement(possibleWebLib, isExistingWebLib);
			// build of map of all unique classpath component contributions from dependent projects
			if(isExistingWebLib){
				IVirtualComponent component = ComponentCore.createComponent(possibleWebLib);
				if(component != null){
					classPathWLPSelection.buildClasspathComponentDependencyMap(component, pathToComp);
				}
			}
		}
		//next handle entries for all other web lib refs
		//e.g. to jars in other projects, or outside the workspace or relative to a var
		for(Iterator iterator = otherExistingWebLibRefs.iterator(); iterator.hasNext();){
			IVirtualReference ref = (IVirtualReference)iterator.next();
			IVirtualComponent referencedComponent = ref.getReferencedComponent();
			// do not add if this is a classpath entry dependency
			if (ClasspathDependencyUtil.isClasspathComponentDependency(referencedComponent)) {
				continue;
			}
			try {
				String unresolvedURI = ModuleURIUtil.getArchiveName(URI.createURI(ModuleURIUtil.getHandleString(referencedComponent)));
				URI archiveURI = URI.createURI(unresolvedURI);
				ClasspathElement element = classPathWLPSelection.createArchiveElement(URI.createURI(ModuleURIUtil.getHandleString(referencedComponent)), referencedComponent.getName(), archiveURI.lastSegment());
				classPathWLPSelection.addClasspathElement(element, unresolvedURI);
			} catch (UnresolveableURIException e) {
				J2EEPlugin.logError(e);
			}
		}
		
		// add ClasspathElements for all dependent project cp dependencies
		final Iterator it = pathToComp.values().iterator();
		while (it.hasNext()) {
			final IVirtualComponent c = (IVirtualComponent) it.next();
			final URI archiveURI = URI.createURI(ModuleURIUtil.getHandleString(c));
			String unresolvedURI = null;
			try {
				unresolvedURI = ModuleURIUtil.getArchiveName(archiveURI);
			} catch (UnresolveableURIException e) {
				J2EEPlugin.logError(e);
			}
			if (unresolvedURI != null) {
				final ClasspathElement element = classPathWLPSelection.createClasspathArchiveElement(c.getProject(), archiveURI, unresolvedURI);
				classPathWLPSelection.addClasspathElement(element, unresolvedURI);
			}
		}
		// Add elements for raw classpath entries (either already tagged or potentially taggable) 
		try {
			classPathWLPSelection.createClasspathEntryElements(component, WEBLIB, WEBINF_CLASSES);
		} catch (CoreException ce) {
			J2EEPlugin.logError(ce);
		}
	}

	public boolean isWLPModel() {
		return isWLPModel;
	}

}
