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

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.jst.j2ee.internal.J2EEVersionConstants;
import org.eclipse.jst.j2ee.internal.common.J2EEVersionUtil;
import org.eclipse.jst.j2ee.internal.componentcore.JavaEEBinaryComponentHelper;
import org.eclipse.jst.j2ee.internal.plugin.J2EEPlugin;
import org.eclipse.jst.j2ee.internal.project.J2EEProjectUtilities;
import org.eclipse.jst.j2ee.project.JavaEEProjectUtilities;
import org.eclipse.jst.jee.util.internal.JavaEEQuickPeek;
import org.eclipse.wst.common.componentcore.ComponentCore;
import org.eclipse.wst.common.componentcore.internal.StructureEdit;
import org.eclipse.wst.common.componentcore.internal.flat.IChildModuleReference;
import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
import org.eclipse.wst.common.componentcore.resources.IVirtualReference;
import org.eclipse.wst.server.core.IModule;
import org.eclipse.wst.server.core.IModule2;
import org.eclipse.wst.server.core.internal.Module;
import org.eclipse.wst.server.core.internal.ModuleFactory;
import org.eclipse.wst.server.core.internal.ServerPlugin;
import org.eclipse.wst.server.core.model.ModuleDelegate;
import org.eclipse.wst.server.core.util.ProjectModuleFactoryDelegate;
import org.eclipse.wst.web.internal.deployables.FlatComponentDeployable;

/**
 * J2EE module factory.
 */
public class J2EEDeployableFactory extends ProjectModuleFactoryDelegate implements IResourceChangeListener {
	protected Map <IModule, FlatComponentDeployable> moduleDelegates = new HashMap<IModule, FlatComponentDeployable>(5);

	public static final String J2EE_ID = "org.eclipse.jst.j2ee.server"; //$NON-NLS-1$
	public static final String BINARY_PREFIX = "/binary:"; //$NON-NLS-1$
	
	public static J2EEDeployableFactory J2EE_INSTANCE;
	public static J2EEDeployableFactory j2eeInstance() {
		if( J2EE_INSTANCE == null ) {
			ensureFactoryLoaded(J2EE_ID);
		}
		return J2EE_INSTANCE;
	}
	
	public static void ensureFactoryLoaded(String factoryId) {
        ModuleFactory[] factories = ServerPlugin.getModuleFactories();
        for( int i = 0; i < factories.length; i++ ) {
                if( factories[i].getId().equals(factoryId)) {
                        factories[i].getDelegate(new NullProgressMonitor());
                }
        }
	}
	
	public J2EEDeployableFactory() {
		super();
	}
	
	@Override
	public void initialize() {
		super.initialize();
		if( getId().equals(J2EE_ID))
			J2EE_INSTANCE = this;
		ResourcesPlugin.getWorkspace().addResourceChangeListener(this);
	}
	
	@Override
	protected IModule[] createModules(IProject project) {
		IVirtualComponent component = ComponentCore.createComponent(project);
		if(component != null)
			return createModuleDelegates(component);
		return null;
	}


	@Override
	public ModuleDelegate getModuleDelegate(IModule module) {
		if (module == null)
			return null;

		ModuleDelegate md = moduleDelegates.get(module);
		if( md == null && ((Module)module).getInternalId().startsWith(BINARY_PREFIX))
			return createDelegate(module);
		
		if (md == null) {
			createModules(module.getProject());
			md = moduleDelegates.get(module);
		}
		return md;
	}

	protected boolean canHandleProject(IProject p) {
		// First check the component is of type Java EE, then check J2EE version
		IVirtualComponent comp = ComponentCore.createComponent(p);
		return (JavaEEProjectUtilities.usesJavaEEComponent(comp) && J2EEProjectUtilities.isLegacyJ2EEProject(p));
	}
	
	protected IModule[] createModuleDelegates(IVirtualComponent component) {
		if(component == null){
			return null;
		}
		
		List<IModule> projectModules = new ArrayList<IModule>();
		try {
			if (canHandleProject(component.getProject())) {
				String type = JavaEEProjectUtilities.getJ2EEProjectType(component.getProject());
				String version = J2EEProjectUtilities.getJ2EEProjectVersion(component.getProject());
				Map<String, String> props = new HashMap<String, String>();
				String componentName = component.getName();
				String deployedName = component.getDeployedName();
				props.put(IModule2.PROP_DEPLOY_NAME, component.getDeployedName());
				if (componentName != null && deployedName != null && !componentName.equals(deployedName)) {
					// Only set the display name if the deploy name and the module name are different.
					props.put(IModule2.PROP_DISPLAY_NAME, componentName + "(" + deployedName + ")");  //$NON-NLS-1$//$NON-NLS-2$
				}
				IModule module = createModule(component.getName(), component.getName(), type, version, component.getProject(), props);
				FlatComponentDeployable moduleDelegate = createModuleDelegate(component.getProject(), component);
				moduleDelegates.put(module, moduleDelegate);
				projectModules.add(module);

				// Check to add any binary modules
				if (J2EEProjectUtilities.ENTERPRISE_APPLICATION.equals(type))
					projectModules.addAll(LEGACY_createBinaryModules(component));
			} else {
				return null;
			}
		} catch (Exception e) {
			e.printStackTrace();
			J2EEPlugin.logError(e);
		}
		return projectModules.toArray(new IModule[projectModules.size()]);
	}

	protected FlatComponentDeployable createModuleDelegate(IProject project, IVirtualComponent component) {
		return new J2EEFlexProjDeployable(project, component);
	}

	/**
	 * These are here so that previous modules are able to be found 
	 * 
	 * @param component
	 * @return
	 */
	protected List<IModule> LEGACY_createBinaryModules(IVirtualComponent component) {
		List<IModule> projectModules = new ArrayList<IModule>();
		IVirtualReference[] references = component.getReferences();
		for (int i = 0; i < references.length; i++) {
			IVirtualComponent moduleComponent = references[i].getReferencedComponent();
			if( moduleComponent.isBinary()) {
				JavaEEQuickPeek quickPeek = JavaEEBinaryComponentHelper.getJavaEEQuickPeek(moduleComponent);
				IModule nestedModule = createModule(quickPeek,moduleComponent.getName(),
						moduleComponent.getDeployedName(), moduleComponent.getProject());
				if (nestedModule != null) {
					FlatComponentDeployable moduleDelegate = getNestedDelegate(moduleComponent);
					moduleDelegates.put(nestedModule, moduleDelegate);
					projectModules.add(nestedModule);
				}
			}
		}

		return projectModules;
	}
	
	protected FlatComponentDeployable getNestedDelegate(IVirtualComponent component) {
		return new J2EEFlexProjDeployable(component.getProject(), component);
	}

	protected IModule createModule(JavaEEQuickPeek quickPeek, String id, String name, IProject project) {
		if (quickPeek.getType() == JavaEEQuickPeek.UNKNOWN) {
			return null;
		}

		String moduleType = null;
		String moduleVersion = null;

		switch (quickPeek.getType()) {
		case JavaEEQuickPeek.APPLICATION_CLIENT_TYPE:
			moduleType = J2EEProjectUtilities.APPLICATION_CLIENT;
			break;
		case JavaEEQuickPeek.WEB_TYPE:
			moduleType = JavaEEProjectUtilities.DYNAMIC_WEB;
			break;
		case JavaEEQuickPeek.EJB_TYPE:
			moduleType = JavaEEProjectUtilities.EJB;
			break;
		case JavaEEQuickPeek.CONNECTOR_TYPE:
			moduleType = JavaEEProjectUtilities.JCA;
			break;
		case JavaEEQuickPeek.APPLICATION_TYPE:
			moduleType = JavaEEProjectUtilities.ENTERPRISE_APPLICATION;
			break;
		case JavaEEQuickPeek.WEBFRAGMENT_TYPE:
			moduleType = JavaEEProjectUtilities.WEBFRAGMENT;
			break;
		default:
			moduleType = JavaEEProjectUtilities.UTILITY;
			moduleVersion = J2EEVersionConstants.VERSION_1_0_TEXT;
		}

		int version = quickPeek.getVersion();
		moduleVersion = J2EEVersionUtil.convertVersionIntToString(version);

		IModule nestedModule = createModule(id, name, moduleType, moduleVersion, project);
		return nestedModule;
	}
	
	/**
	 * Returns the list of resources that the module should listen to for state
	 * changes. The paths should be project relative paths. Subclasses can
	 * override this method to provide the paths.
	 * 
	 * @return a possibly empty array of paths
	 */
	@Override
	protected IPath[] getListenerPaths() {
		return new IPath[] { new Path(".project"), // nature //$NON-NLS-1$
				new Path(StructureEdit.MODULE_META_FILE_NAME), // component
				new Path(".settings/org.eclipse.wst.common.project.facet.core.xml") // facets //$NON-NLS-1$
		};
	}

	@Override
	protected void clearCache(IProject project) {
		super.clearCache(project);
		List<IModule> modulesToRemove = null;
		for (Iterator<IModule> iterator = moduleDelegates.keySet().iterator(); iterator.hasNext();) {
			IModule module = iterator.next();
			if (module.getProject() != null && module.getProject().equals(project)) {
				if (modulesToRemove == null) {
					modulesToRemove = new ArrayList<IModule>();
				}
				modulesToRemove.add(module);
			}
		}
		if (modulesToRemove != null) {
			for (IModule module : modulesToRemove) {
				moduleDelegates.remove(module);
			}
		}
	}
	
	/**
	 * From this point on, when queried, projects will generate their binary 
	 * child modules on the fly and they will be small and dumb
	 * 
	 * @param parent
	 * @param child
	 * @return
	 */
	public IModule createChildModule(FlatComponentDeployable parent, IChildModuleReference child) {
		File file = child.getFile();
		if( file != null ) {
			IPath p = new Path(file.getAbsolutePath());
			JavaEEQuickPeek qp = JavaEEBinaryComponentHelper.getJavaEEQuickPeek(p);
			IModule module = createModule(qp, BINARY_PREFIX + file.getAbsolutePath(), file.getName(), parent.getProject());
			FlatComponentDeployable moduleDelegate = getNestedDelegate(child.getComponent());
			moduleDelegates.put(module, moduleDelegate);
			return module;
		}
		return null;
	}
	
	/**
	 * Create a module delegate on the fly for this binary file
	 * @param module
	 * @return
	 */
	public ModuleDelegate createDelegate(IModule module) {
		String internalId = ((Module)module).getInternalId();
		String path = internalId.substring(BINARY_PREFIX.length());
		File f = new File(path);
		return new BinaryFileModuleDelegate(f);
	}

	@Override
	public void resourceChanged(IResourceChangeEvent event) {
		// If it is only a marker change, ignore the change 
		if(event.getDelta() == null || event.getDelta().getFlags() == IResourceDelta.MARKERS) {
			return;
		}
		cleanAllDelegates();
	}
	
	protected void cleanAllDelegates() {
		Iterator<FlatComponentDeployable> i = moduleDelegates.values().iterator();
		while(i.hasNext()) {
			i.next().clearCache();
		}
		clearModuleCache();
		modulesChanged();
	}

	@Override
	public void clearModuleCache() {
		clearCache(null);
	}
}
