/*******************************************************************************
 * Copyright (c) 2009 Red Hat 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:
 *     Red Hat - 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.List;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdapterFactory;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.wst.common.componentcore.ComponentCore;
import org.eclipse.wst.common.componentcore.internal.flat.FlatVirtualComponent;
import org.eclipse.wst.common.componentcore.internal.flat.FlatVirtualComponent.FlatComponentTaskModel;
import org.eclipse.wst.common.componentcore.internal.flat.IChildModuleReference;
import org.eclipse.wst.common.componentcore.internal.flat.IFlatFile;
import org.eclipse.wst.common.componentcore.internal.flat.IFlatFolder;
import org.eclipse.wst.common.componentcore.internal.flat.IFlatResource;
import org.eclipse.wst.common.componentcore.internal.flat.IFlatVirtualComponent;
import org.eclipse.wst.common.componentcore.internal.flat.IFlattenParticipant;
import org.eclipse.wst.common.componentcore.internal.util.VirtualReferenceUtilities;
import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
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.model.IModuleFile;
import org.eclipse.wst.server.core.model.IModuleFolder;
import org.eclipse.wst.server.core.model.IModuleResource;
import org.eclipse.wst.server.core.model.ModuleDelegate;
import org.eclipse.wst.server.core.util.ModuleFile;
import org.eclipse.wst.server.core.util.ProjectModule;

public abstract class FlatComponentDeployable extends ProjectModule {

	/*
	 * Register an adapt IModule to IVirtualComponent 
	 */
	static {
		Platform.getAdapterManager().registerAdapters(new IAdapterFactory() {
			public Class[] getAdapterList() {
				return new Class[] { IVirtualComponent.class };
			}

			public Object getAdapter(Object adaptableObject, Class adapterType) {
				if (adaptableObject instanceof IModule) {
					IModule module = (IModule) adaptableObject;
					FlatComponentDeployable deployable = (FlatComponentDeployable) module.loadAdapter(FlatComponentDeployable.class, null);
					if(deployable != null){
						IVirtualComponent virtualComponent = deployable.getComponent();
						return virtualComponent;
					}
				}
				return null;
			}
		}, IModule.class);
	}
	
	protected IVirtualComponent component = null;
	protected List<IModuleResource> members = new ArrayList<IModuleResource>();
	
	public FlatComponentDeployable(IProject project) {
		this(project,ComponentCore.createComponent(project));
	}
	
	public FlatComponentDeployable(IProject project, IVirtualComponent aComponent) {
		super(project);
		this.component = aComponent;
	}

	public IVirtualComponent getComponent() {
		return component;
	}
	
	/**
	 * We will cache the flattened piece here, and instead redirect
	 * the module factories to recreate the modules *whenever* there is 
	 * a workspace change. This will still be much more efficient than
	 * traversing the tree each time a call to getResources() or getChildModules(). 
	 */
	private FlatVirtualComponent cacheFlattened = null;

	
	public boolean shouldCache() {
		return false;
	}
	
	public void clearCache() {
		cacheFlattened = null;
	}
	
	/**
	 * The export model is what does the grunt of the work
	 * @return
	 */
	protected IFlatVirtualComponent getFlatComponent() {
		if( !shouldCache() || cacheFlattened == null ) {
			FlatComponentTaskModel options = new FlatComponentTaskModel();
			options.put(FlatVirtualComponent.PARTICIPANT_LIST, Arrays.asList(getParticipants()));
			FlatVirtualComponent tmp = new FlatVirtualComponent(component, options);
			if( shouldCache())
				cacheFlattened = tmp;
			return tmp;
		}
		return cacheFlattened;
	}
	
	/**
	 * Subclasses can provide a list of participants who may
	 * be involved in forming the export model
	 * 
	 * A deployable with no participant should still properly
	 * consume consumed references and traverse the model appropriately
	 * 
	 * @return
	 */
	protected IFlattenParticipant[] getParticipants() {
		return new IFlattenParticipant[]{
		};
	}
	
	public boolean isBinary() {
		return component == null ? false : component.isBinary();
	}

	@Override
	public IModuleResource[] members() throws CoreException {
		if( component.isBinary() ) 
			return LEGACY_binaryMembers();
		
		IFlatVirtualComponent em = getFlatComponent();
		IFlatResource[] resources = em.fetchResources();
		return convert(resources);
		
	}

	protected IModuleResource[] LEGACY_binaryMembers() {
		IFile ifile = (IFile)component.getAdapter(IFile.class);
		File file = (File)component.getAdapter(File.class);
		ModuleFile mf = ifile != null ? new ModuleFile(ifile, ifile.getName(), new Path(""))  //$NON-NLS-1$
		 		: new ModuleFile(file, file.getName(), new Path("")); //$NON-NLS-1$
		return new IModuleResource[]{mf};
	}
	
	 /**
     * Returns the child modules of this module.
     * 
     * @return org.eclipse.wst.server.core.model.IModule[]
     */
    @Override
	public IModule[] getChildModules() {
        return getModules();
    }
    
    public /* non api */ IChildModuleReference[] getExportModelChildren() throws CoreException {
    	IFlatVirtualComponent em = getFlatComponent();
    	IChildModuleReference[] children = em.getChildModules();
    	return children;
    }
    
    public IModule[] getModules() {
    	// Legacy, here in case the old modules are used
    	if( component.isBinary() ) 
    		return new IModule[]{};
    		
    	try {
    		List<IModule> modules = new ArrayList<IModule>();
	    	IChildModuleReference[] children = getExportModelChildren();
	    	for( int i = 0; i < children.length; i++ ) {
	    		IModule child = gatherModuleReference(component, children[i]);
	    		if( child != null )
	    			modules.add(child);
	    	}
	    	return modules.toArray(new IModule[modules.size()]);
    	} catch( CoreException ce ) {
    	}
    	return new IModule[]{};
	}
    
	@Override
	public String getPath(IModule m) {
		return getURI(m);
	}

	/**
	 * Returns the URI of the given contained CHILD module.
	 * 
	 * SOFT requirements (NOT API!!) in use by some adopters
	 * If the passed in module is equal to this module, return our own deployed name
	 *
	 * @param module a module
	 * @return the URI of the given module, or <code>null</code> if the URI could
	 *    not be found
	 */
	public String getURI(IModule module) {
		ProjectModule md = (ProjectModule)module.loadAdapter(ProjectModule.class, new NullProgressMonitor());
		if( md == this ) {
			// guess my own name
			return VirtualReferenceUtilities.INSTANCE.getDefaultProjectArchiveName(this.component);
		}
		try {
			FlatComponentDeployable cd = (FlatComponentDeployable)module.loadAdapter(FlatComponentDeployable.class, new NullProgressMonitor());
			if( cd != null ) {
		    	IFlatVirtualComponent em = getFlatComponent();
		    	IChildModuleReference[] children = em.getChildModules();
		    	for( int i = 0; i < children.length; i++ ) {
		    		IModule child = gatherModuleReference(component, children[i]);
		    		if( child != null && child.getId().equals(module.getId()))
		    			return children[i].getRelativeURI().toString();
		    	}
			}
		} catch( CoreException ce ) {
		}
		return null;
	}
    
    /**
     * If I know how to find an IModule for this child, do so now
     * 
     * I would love to see this replaced with some API to locate a 
     * possible child module based on a virtual component.
     * 
     * @param component
     * @param targetComponent
     * @return
     */
    protected IModule gatherModuleReference(IVirtualComponent component, IChildModuleReference child) {
    	// Handle workspace project module components
    	// Subclasses should extend 
    	IVirtualComponent targetComponent = child.getComponent();
    	if (targetComponent != null && targetComponent.getProject()!=component.getProject()) {
			if (!targetComponent.isBinary()) {
				IModule[] allMods = ServerUtil.getModules(targetComponent.getProject());
				for( int i = 0; i < allMods.length; i++ ) {
					ModuleDelegate md = (ModuleDelegate)allMods[i].loadAdapter(ModuleDelegate.class, new NullProgressMonitor());
					if( md instanceof ProjectModule) {
						return allMods[i];
					}
				}
				return allMods.length > 0 ? allMods[0] : null;
			}
		}
		return null;
    }
    	
    
    
    /*
     * Below are STATIC utility classes and methods
     */

	protected static IModuleResource[] convert(IFlatResource[] resources) {
		ArrayList<IModuleResource> list = new ArrayList<IModuleResource>();
		for( int i = 0; i < resources.length; i++ ) {
			if( resources[i] instanceof IFlatFile)
				list.add(new ComponentModuleFile(resources[i]));
			else if( resources[i] instanceof IFlatFolder) 
				list.add(new ComponentModuleFolder(resources[i]));
		}
		return list.toArray(new IModuleResource[list.size()]);
	}
	
	public static class ComponentModuleResource {
		protected IFlatResource delegate;
		public ComponentModuleResource(IFlatResource resource) {
			this.delegate = resource;
		}
		public long getModificationStamp() {
			return ((IFlatFile)delegate).getModificationStamp();
		}
		
		public IPath getModuleRelativePath() {
			return delegate.getModuleRelativePath();
		}
		public String getName() {
			return delegate.getName();
		}
		public Object getAdapter(Class adapter) {
			return delegate.getAdapter(adapter);
		}
		public IModuleResource[] members() {
			IFlatResource[] children = ((IFlatFolder)delegate).members();
			return convert(children);
		}
	}

	public static class ComponentModuleFile extends ComponentModuleResource implements IModuleFile{
		public ComponentModuleFile(IFlatResource resource) {
			super(resource);
		}
		
		@Override
		public boolean equals(Object obj) {
			if (obj == this)
				return true;
			
			if (!(obj instanceof IModuleFile))
				return false;
			
			IModuleFile mf = (IModuleFile) obj;
			if (!getName().equals(mf.getName()))
				return false;
			if (!getModuleRelativePath().equals(mf.getModuleRelativePath()))
				return false;
			return true;
		}
		
		@Override
		public int hashCode() {
			return getName().hashCode() * 37 + getModuleRelativePath().hashCode();
		}
	}

	public static class ComponentModuleFolder extends ComponentModuleResource implements IModuleFolder {
		public ComponentModuleFolder(IFlatResource resource) {
			super(resource);
		}

		@Override
		public boolean equals(Object obj) {
			if (obj == this)
				return true;
			
			if (!(obj instanceof IModuleFolder))
				return false;
			
			IModuleFolder mf = (IModuleFolder) obj;
			if (!getName().equals(mf.getName()))
				return false;
			if (!getModuleRelativePath().equals(mf.getModuleRelativePath()))
				return false;
			return true;
		}
		
		@Override
		public int hashCode() {
			return getName().hashCode() * 37 + getModuleRelativePath().hashCode();
		}
		
	}

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