/*******************************************************************************
 * Copyright (c) 2003, 2005 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.wst.web.internal.deployables;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.wst.common.componentcore.ArtifactEdit;
import org.eclipse.wst.common.componentcore.ComponentCore;
import org.eclipse.wst.common.componentcore.internal.resources.VirtualArchiveComponent;
import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
import org.eclipse.wst.common.componentcore.resources.IVirtualContainer;
import org.eclipse.wst.common.componentcore.resources.IVirtualFolder;
import org.eclipse.wst.common.componentcore.resources.IVirtualReference;
import org.eclipse.wst.common.componentcore.resources.IVirtualResource;
import org.eclipse.wst.common.project.facet.core.IFacetedProject;
import org.eclipse.wst.common.project.facet.core.IProjectFacet;
import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;
import org.eclipse.wst.server.core.IModule;
import org.eclipse.wst.server.core.ServerUtil;
import org.eclipse.wst.server.core.internal.ModuleFile;
import org.eclipse.wst.server.core.internal.ModuleFolder;
import org.eclipse.wst.server.core.model.IModuleFolder;
import org.eclipse.wst.server.core.model.IModuleResource;
import org.eclipse.wst.server.core.util.ProjectModule;

public abstract class ComponentDeployable extends ProjectModule {

	protected IVirtualComponent component = null;
	protected List members = new ArrayList();
	
	public ComponentDeployable(IProject project) {
		this(project,ComponentCore.createComponent(project));
	}
	
	public ComponentDeployable(IProject project, IVirtualComponent aComponent) {
		super(project);
		this.component = aComponent;
	}
	
	/**
	 * @see org.eclipse.jst.server.core.IJ2EEModule#isBinary()
	 */
	public boolean isBinary() {
		if (component==null)
			return false;
		return component.isBinary();
	}
	
	/**
	 * Add the resources from mr to the existing resources in Module Folder mf
	 * @param ModuleFolder mf
	 * @param IModuleResource[] mr
	 */
	private void addMembersToModuleFolder(ModuleFolder mf, IModuleResource[] mr) {
		// If the folder is null or the resources to add are null or empty, bail and return
		if (mf == null || mr == null || mr.length==0) 
			return;
		// Get the existing members in the module folder
		IModuleResource[] mf_members = mf.members();
		int mf_size = 0;
		// Get the length of the existing members in the module folder
		if (mf_members != null)
			mf_size = mf_members.length;
		// Create a new array to set on the module folder which will combine the existing and
		// new module resources
		IModuleResource[] res = new IModuleResource[mf_size + mr.length];
		// Copy the existing members into the array if there are any
		if (mf_members != null && mf_size > 0)
			System.arraycopy(mf_members, 0, res, 0, mf_size);
		// Copy the new members into the array
		System.arraycopy(mr, 0, res, mf_size, mr.length);
		// Set the new members array on the module folder
		mf.setMembers(res);
	}

	 /**
     * Returns the child modules of this module.
     * 
     * @return org.eclipse.wst.server.core.model.IModule[]
     */
    public IModule[] getChildModules() {
        return getModules();
    }
    
    public IModule[] getModules() {
		List modules = new ArrayList();
		if (component != null) {
	    	IVirtualReference[] components = getReferences(component);
	    	for (int i = 0; i < components.length; i++) {
				IVirtualReference reference = components[i];
				if (reference != null && reference.getDependencyType()==IVirtualReference.DEPENDENCY_TYPE_USES) {
					IVirtualComponent virtualComp = reference.getReferencedComponent();
					IModule module = gatherModuleReference(component, virtualComp);
					if (module != null && !modules.contains(module))
						modules.add(module);
				}
			}
		}
        return (IModule[]) modules.toArray(new IModule[modules.size()]);
	}
    
    protected IVirtualReference[] getReferences(IVirtualComponent aComponent) {
    	return aComponent.getReferences();
    }
    
    protected IModule gatherModuleReference(IVirtualComponent component, IVirtualComponent targetComponent ) {
    	// Handle workspace project module components
		if (targetComponent != null && targetComponent.getProject()!=component.getProject()) {
			if (!targetComponent.isBinary())
				return ServerUtil.getModule(targetComponent.getProject());
		}
		return null;
    }
    
    /**
	 * Find the module resources for a given container and path. Inserts in the java containers
	 * at a given path if not null.
	 * 
	 * @param cont a container
	 * @param path the current module relative path
	 * @param javaPath the path where Java resources fit in the root
	 * @param javaCont
	 * @return a possibly-empty array of module resources
	 * @throws CoreException
	 */
	protected IModuleResource[] getMembers(IContainer cont, IPath path, IPath javaPath, IContainer[] javaCont) throws CoreException {
		IResource[] res = cont.members();
		int size2 = res.length;
		List list = new ArrayList(size2);
		for (int j = 0; j < size2; j++) {
			if (res[j] instanceof IContainer) {
				IContainer cc = (IContainer) res[j];
				
				IPath newPath = path.append(cc.getName()).makeRelative();
				// Retrieve already existing module folder if applicable
				ModuleFolder mf = (ModuleFolder) getExistingModuleResource(members,newPath);
				if (mf == null) {
					mf = new ModuleFolder(cc, cc.getName(), path);
					ModuleFolder parent = (ModuleFolder) getExistingModuleResource(members, path);
					if (path.isEmpty())
						members.add(mf);
					else {
						if (parent == null)
							parent = ensureParentExists(path, cc);
						addMembersToModuleFolder(parent, new IModuleResource[] {mf});
					}
				}
				IModuleResource[] mr = getMembers(cc, newPath, javaPath, javaCont);
				
				if (javaPath != null && newPath.isPrefixOf(javaPath))
					mr = handleJavaPath(path, javaPath, newPath, javaCont, mr, cc);

				addMembersToModuleFolder(mf, mr);
				
			} else {
				IFile f = (IFile) res[j];
				// Handle the default package case
				if (path.equals(javaPath)) {
					ModuleFolder mFolder = (ModuleFolder) getExistingModuleResource(members,javaPath);
					ModuleFile mFile = new ModuleFile(f, f.getName(), javaPath, f.getModificationStamp() + f.getLocalTimeStamp());
					if (mFolder != null)
						addMembersToModuleFolder(mFolder,new IModuleResource[]{mFile});
					else
						list.add(mFile);
				} else {
					ModuleFile mf = new ModuleFile(f, f.getName(), path, f.getModificationStamp() + f.getLocalTimeStamp());
					list.add(mf);
				}
			}
		}
		IModuleResource[] mr = new IModuleResource[list.size()];
		list.toArray(mr);
		return mr;
	}
	
	protected IModuleResource[] getMembers(IVirtualContainer cont, IPath path) throws CoreException {
		IVirtualResource[] res = cont.members();
		int size2 = res.length;
		List list = new ArrayList(size2);
		for (int j = 0; j < size2; j++) {
			if (res[j] instanceof IVirtualContainer) {
				IVirtualContainer cc = (IVirtualContainer) res[j];
				// Retrieve already existing module folder if applicable
				ModuleFolder mf = (ModuleFolder) getExistingModuleResource(members,path.append(new Path(cc.getName()).makeRelative()));
				if (mf == null) {
					mf = new ModuleFolder((IContainer)cc.getUnderlyingResource(), cc.getName(), path);
					ModuleFolder parent = (ModuleFolder) getExistingModuleResource(members, path);
					if (path.isEmpty())
						members.add(mf);
					else {
						if (parent == null)
							parent = ensureParentExists(path, (IContainer)cc.getUnderlyingResource());
						addMembersToModuleFolder(parent, new IModuleResource[] {mf});
					}
				}
				IModuleResource[] mr = getMembers(cc, path.append(cc.getName()));
				addMembersToModuleFolder(mf, mr);
			} else {
				IFile f = (IFile) res[j].getUnderlyingResource();
				if (shouldAddComponentFile(f)) {
					ModuleFile mf = new ModuleFile(f, f.getName(), path, f.getModificationStamp() + f.getLocalTimeStamp());
					list.add(mf);
				}
			}
		}
		IModuleResource[] mr = new IModuleResource[list.size()];
		list.toArray(mr);
		return mr;
	}
	
	protected ModuleFolder ensureParentExists(IPath path, IContainer cc) {
		ModuleFolder parent = (ModuleFolder) getExistingModuleResource(members, path);
		if (parent == null) {
			String folderName = path.lastSegment();
			IPath folderPath = Path.EMPTY;
			if (path.segmentCount()>1)
				folderPath = path.removeLastSegments(1);
			parent = new ModuleFolder(cc, folderName, folderPath);
			if (path.segmentCount()>1)
				addMembersToModuleFolder(ensureParentExists(path.removeLastSegments(1),cc), new IModuleResource[] {parent});
			else
				members.add(parent);
		}
		return parent;
	}
	
	/**
	 * This method is meant to be overridden by subclasses.  Return whether or not to add this file
	 * to the members list.
	 * 
	 * @param file
	 * @return boolean should add file?
	 */
	protected boolean shouldAddComponentFile(IFile file) {
		return true;
	}
	
	/**
	 * Check the current cache to see if we already have an existing module resource for
	 * the given path.
	 * @param aList
	 * @param path
	 * @return an existing moduleResource from the cached result
	 */
	 
	protected IModuleResource getExistingModuleResource(List aList, IPath path) { 
    	// If the list is empty, return null
    	if (aList==null || aList.isEmpty() || path == null)
    		return null;
    	// Otherwise recursively check to see if given resource matches current resource or if it is a child
    	String[] pathSegments = path.segments(); 
    	IModuleResource moduleResource = null;
    	
    	if(pathSegments.length == 0)
    		return null;
    	for (Iterator iter = aList.iterator(); iter.hasNext();) {
    		moduleResource = (IModuleResource) iter.next();     	
    		String[] moduleSegments = moduleResource.getModuleRelativePath().segments();
    		// If the last segment in passed in path equals the module resource name 
    		// and segment count is the same and the path segments start with the module path segments
    		// then we have a match and we return the existing moduleResource
    		if (pathSegments[pathSegments.length - 1].equals(moduleResource.getName()) && 
		    		(moduleSegments.length + 1) == pathSegments.length && 
		    		startsWith(moduleSegments, pathSegments))
		    	return moduleResource; 
    		
    		// Otherwise, if it is a folder, check its children for the existing resource path
    		// but only check if the beginning segments are a match
	    	if(moduleResource instanceof IModuleFolder && 
	    			startsWith(moduleSegments, pathSegments) && pathSegments.length > moduleSegments.length &&
	    			moduleResource.getName().equals(pathSegments[moduleSegments.length > 0 ? moduleSegments.length : 0]))	    	  
    			if (((IModuleFolder)moduleResource).members()!=null)
    				return getExistingModuleResource(Arrays.asList(((IModuleFolder)moduleResource).members()),path);		
    	}
    	return null;
    }
	
	/**
	 * 
	 * @param beginningSegments
	 * @param testSegments
	 * @return True if beginningSegments[i] == testSegments[i] for all 0<=i<beginningSegments[i] 
	 */
	private boolean startsWith(String[] beginningSegments, String[] testSegments) { 
		for(int i=0; i < beginningSegments.length; i++) {
			if(!beginningSegments[i].equals(testSegments[i]))
				return false;
		}
		return true;
	}

	protected IModuleResource[] handleJavaPath(IPath path, IPath javaPath, IPath curPath, IContainer[] javaCont, IModuleResource[] mr, IContainer cc) throws CoreException {
		//subclasses may override
		return new IModuleResource[]{};
	}
	
	public IModuleResource[] members() throws CoreException {
		members.clear();
		IVirtualComponent vc = ComponentCore.createComponent(getProject());
		if (vc != null) {
			IVirtualFolder vFolder = vc.getRootFolder();
			IModuleResource[] mr = getMembers(vFolder, Path.EMPTY);
			int size = mr.length;
			for (int j = 0; j < size; j++) {
				members.add(mr[j]);
			}
			addUtilMembers(vc);
		}
		
		IModuleResource[] mr = new IModuleResource[members.size()];
		members.toArray(mr);
		return mr;
	}
	
	protected boolean shouldIncludeUtilityComponent(IVirtualComponent virtualComp, IVirtualReference[] references, ArtifactEdit edit) {
		return virtualComp != null && virtualComp.isBinary() && virtualComp.getProject()==component.getProject();
	}
	
	protected void addUtilMembers(IVirtualComponent vc) {
		ArtifactEdit edit = null;
		try {
			edit = getComponentArtifactEditForRead();
			IVirtualReference[] components = vc.getReferences();
	    	for (int i = 0; i < components.length; i++) {
				IVirtualReference reference = components[i];
				IVirtualComponent virtualComp = reference.getReferencedComponent();
				if (shouldIncludeUtilityComponent(virtualComp,components,edit)) {
					ModuleFile mf = null;
					String archiveName = reference.getArchiveName();
					IPath archivePath = ((VirtualArchiveComponent)virtualComp).getWorkspaceRelativePath();
					if (archivePath != null) { //In Workspace
						IFile utilFile = ResourcesPlugin.getWorkspace().getRoot().getFile(archivePath);
						String name = null != archiveName ? archiveName : utilFile.getName();
						mf = new ModuleFile(utilFile, name, reference.getRuntimePath().makeRelative());
					}
					else {
						File extFile = ((VirtualArchiveComponent)virtualComp).getUnderlyingDiskFile();
						String name = null != archiveName ? archiveName : extFile.getName();
						mf = new ModuleFile(extFile, name, reference.getRuntimePath().makeRelative());
					}
					if (mf == null)
						continue;
					IModuleResource moduleParent = getExistingModuleResource(members, mf.getModuleRelativePath());
					
					if (moduleParent != null && moduleParent instanceof ModuleFolder)
						addMembersToModuleFolder((ModuleFolder)moduleParent, new IModuleResource[]{mf});
					else {
						if (mf.getModuleRelativePath().isEmpty())
							members.add(mf);
						else {
							if (moduleParent == null)
								moduleParent = ensureParentExists(mf.getModuleRelativePath(), (IContainer)vc.getRootFolder().getUnderlyingResource());
							addMembersToModuleFolder((ModuleFolder)moduleParent, new IModuleResource[] {mf});
						}
					}
				}
	    	}
		} finally {
			if (edit!=null)
				edit.dispose();
		}
	}
	
	protected ArtifactEdit getComponentArtifactEditForRead() {
		return null;
	}

	protected static boolean isProjectOfType(IProject project, String typeID) {
		IFacetedProject facetedProject = null;
		try {
			facetedProject = ProjectFacetsManager.create(project);
		} catch (CoreException e) {
			return false;
		}
		
		if (facetedProject !=null && ProjectFacetsManager.isProjectFacetDefined(typeID)) {
			IProjectFacet projectFacet = ProjectFacetsManager.getProjectFacet(typeID);
			return projectFacet!=null && facetedProject.hasProjectFacet(projectFacet);
		}
		return false;
	}

	/**
	 * Returns the root folders for the resources in this module.
	 * 
	 * @return a possibly-empty array of resource folders
	 */
	public IContainer[] getResourceFolders() {
		IVirtualComponent vc = ComponentCore.createComponent(getProject());
		if (vc != null) {
			IVirtualFolder vFolder = vc.getRootFolder();
			if (vFolder != null)
				return vFolder.getUnderlyingFolders();
		}
		return new IContainer[]{};
	}

}
