/*******************************************************************************
 * 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.HashSet;
import java.util.List;
import java.util.Set;

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.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) {
		super(project);
		this.component = ComponentCore.createComponent(project);
	}
	
	/**
	 * @see org.eclipse.jst.server.core.IJ2EEModule#isBinary()
	 */
	public boolean isBinary() {
		return false;
	}
	
	private void addMembersToModuleFolder(ModuleFolder mf, IModuleResource[] mr) {
		if (mf == null) return;
		Set membersJoin = new HashSet();
		if (mf.members() != null)
			membersJoin.addAll(Arrays.asList(mf.members()));
		if (mr != null && mr.length > 0)
			membersJoin.addAll(Arrays.asList(mr));
		mf.setMembers((IModuleResource[]) membersJoin.toArray(new IModuleResource[membersJoin.size()]));
	}

	 /**
     * 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 = component.getReferences();
	    	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();
					if (virtualComp != null && virtualComp.getProject()!=component.getProject()) {
						Object module = ServerUtil.getModule(virtualComp.getProject());
						if (module != null && !modules.contains(module))
							modules.add(module);
					}
				}
			}
		}
        return (IModule[]) modules.toArray(new IModule[modules.size()]);
	}
    
    /**
	 * 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(), newPath);
					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 (!isFileInSourceContainer(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;
	}
	protected boolean isFileInSourceContainer(IFile file) {
		return false;
	}
	protected IModuleResource getExistingModuleResource(List aList, IPath path) {
    	IModuleResource result = null;
    	// If the list is empty, return null
    	if (aList==null || aList.isEmpty())
    		return null;
    	// Otherwise recursively check to see if given resource matches current resource or if it is a child
    	int i=0;
    	do {
	    	IModuleResource moduleResource = (IModuleResource) aList.get(i);
	    		if (moduleResource.getModuleRelativePath().append(moduleResource.getName()).equals(path))
	    			result = moduleResource;
	    		// if it is a folder, check its children for the resource path
	    		else if (moduleResource instanceof IModuleFolder) {
	    			if (((IModuleFolder)moduleResource).members()!=null)
	    				result = getExistingModuleResource(Arrays.asList(((IModuleFolder)moduleResource).members()),path);
	    		}
	    		i++;
    	} while (result == null && i<aList.size() );
    	return result;
    }
	
	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++) {
				if (!members.contains(mr[j]))
					members.add(mr[j]);
			}
			List utilMembers = getUtilMembers(vc);
			if (!utilMembers.isEmpty())
				members.addAll(utilMembers);
		}
		
		IModuleResource[] mr = new IModuleResource[members.size()];
		members.toArray(mr);
		return mr;
	}
	
	protected List getUtilMembers(IVirtualComponent vc) {
		List utilMembers = new ArrayList();
		IVirtualReference[] components = vc.getReferences();
    	for (int i = 0; i < components.length; i++) {
			IVirtualReference reference = components[i];
			IVirtualComponent virtualComp = reference.getReferencedComponent();
			if (virtualComp != null && virtualComp.isBinary()) {
				IPath archivePath = ((VirtualArchiveComponent)virtualComp).getWorkspaceRelativePath();
				ModuleFile mf = null;
				if (archivePath != null) { //In Workspace
					IFile utilFile = ResourcesPlugin.getWorkspace().getRoot().getFile(archivePath);
					mf = new ModuleFile(utilFile, utilFile.getName(), reference.getRuntimePath().makeRelative());
				}
				else {
					File extFile = ((VirtualArchiveComponent)virtualComp).getUnderlyingDiskFile();
					mf = new ModuleFile(extFile, extFile.getName(), 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});
					}
				}
			}
    	}
    	return utilMembers;	
	}
	
	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[]{};
	}

}
