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

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.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
import org.eclipse.wst.common.componentcore.resources.IVirtualContainer;
import org.eclipse.wst.common.componentcore.resources.IVirtualResource;

/**
 * This utility class is almost entirely copied from ComponentDeployable
 * and deals with the nuts and bolts of creating the model objects when
 * walking a portion of the tree
 */
public class VirtualComponentFlattenUtility {
	public static interface ShouldIncludeUtilityCallback {
		public boolean shouldAddComponentFile(IVirtualComponent current, IFlatFile file);
	}
	
	private List<IFlatResource> members;
	private ShouldIncludeUtilityCallback handler;
	public VirtualComponentFlattenUtility(
			List<IFlatResource> members, ShouldIncludeUtilityCallback handler) {
		this.members = members;
		this.handler = handler;
	}
	
	public void addMembers(IVirtualComponent current, IVirtualContainer cont, IPath path) throws CoreException {
		ensureParentExists(members, path, null);
		FlatResource[] mr = addMembersInternal(current, cont, path);
		int size = mr.length;
		for (int j = 0; j < size; j++) {
			members.add(mr[j]);
		}
	}
	
	// Add this container's children
	public void addContainer(IContainer container, IPath path) throws CoreException {
		IResource[] children = container.members();
		for( int i = 0; i < children.length; i++ ) {
			if( children[i] instanceof IContainer ) {
				addContainerInternal((IContainer)children[i], path);
			} else if( children[i] instanceof IFile ){
				addFile(null, (IFile)children[i], path);
			}
		}
	}
	
	// Physically adds this container
	protected void addContainerInternal(IContainer container, IPath path) throws CoreException {
		IFlatFolder mf = (FlatFolder) getExistingModuleResource(members,path.append(container.getName()).makeRelative());
		if( mf == null ) {
			mf = new FlatFolder(container, container.getName(), path);
			IFlatFolder parent = (FlatFolder) getExistingModuleResource(members, path);
			if (path.isEmpty())
				members.add(mf);
			else {
				if (parent == null)
					parent = ensureParentExists(members, path, container);
				addMembersToModuleFolder(parent, new IFlatResource[] {mf});
			}
		}
		// recurse
		addContainer(container, path.append(container.getName()));
	}
	
	protected FlatResource[] addMembersInternal(IVirtualComponent current, 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];
				IFlatFolder mf = addVirtualContainerInternal(cc, path);
				IFlatResource[] mr = addMembersInternal(current, cc, path.append(cc.getName()));
				addMembersToModuleFolder(mf, mr);
			} else {
				addFile(current, path, (IAdaptable)res[j]);
			}
		}
		FlatResource[] mr = new FlatResource[list.size()];
		list.toArray(mr);
		return mr;
	}
	
	public void addFile(IVirtualComponent current, IPath path, IAdaptable file) {
		IFile f = (IFile)file.getAdapter(IFile.class);
		IFlatFile mf = null;
		if( f != null )
			 mf = createModuleFile(f, path.makeRelative());
		else {
			File f2 = (File)file.getAdapter(File.class);
			if( f2 != null )
				mf = new FlatFile(f2, f2.getName(), path.makeRelative());
		}
		if( mf != null ) {
			if (handler == null || handler.shouldAddComponentFile(current, mf)) {
				if( mf.getModuleRelativePath().isEmpty()) {
					members.remove(mf);
					members.add(mf);
				}
				else {
					IFlatFolder moduleParent = VirtualComponentFlattenUtility.ensureParentExists(members, mf.getModuleRelativePath(), null);
					List tempParentMembers = new ArrayList(Arrays.asList(moduleParent.members()));
					tempParentMembers.remove(mf);
					tempParentMembers.add(mf);
					moduleParent.setMembers((IFlatResource[]) tempParentMembers.toArray(new IFlatResource[tempParentMembers.size()]));
				}
			}
		}
	}
	
	public void addFile(IVirtualComponent current, IFile f, IPath path) {
		addFile(current, path, (IAdaptable)f);
	}
	
	protected IFlatFolder addVirtualContainerInternal(IVirtualContainer cc, IPath path) {
		// Retrieve already existing module folder if applicable
		IFlatFolder mf = (FlatFolder) getExistingModuleResource(members,path.append(cc.getName()).makeRelative());
		if (mf == null) {
			mf = new FlatFolder((IContainer)cc.getUnderlyingResource(), cc.getName(), path);
			IFlatFolder parent = (FlatFolder) getExistingModuleResource(members, path);
			if (path.isEmpty())
				members.add(mf);
			else {
				if (parent == null)
					parent = ensureParentExists(members, path, (IContainer)cc.getUnderlyingResource());
				addMembersToModuleFolder(parent, new IFlatResource[] {mf});
			}
		}
		return mf;
	}
	
	public static FlatFile createModuleFile(final IFile file, final IPath path) {
		return new FlatFile(file, file.getName(), path);
	}

	
	/**
	 * 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
	 */
	 
	public static FlatResource 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(); 
    	FlatResource exportableResource = null;
    	
    	if(pathSegments.length == 0)
    		return null;
    	for (Iterator iter = aList.iterator(); iter.hasNext();) {
    		exportableResource = (FlatResource) iter.next();     	
    		String[] moduleSegments = exportableResource.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(exportableResource.getName()) && 
		    		(moduleSegments.length + 1) == pathSegments.length && 
		    		startsWith(moduleSegments, pathSegments))
		    	return exportableResource; 
    		
    		// 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(exportableResource instanceof FlatFolder && 
	    			startsWith(moduleSegments, pathSegments) && pathSegments.length > moduleSegments.length &&
	    			exportableResource.getName().equals(pathSegments[moduleSegments.length > 0 ? moduleSegments.length : 0]))	    	  
    			if (((FlatFolder)exportableResource).members()!=null)
    				return getExistingModuleResource(Arrays.asList(((FlatFolder)exportableResource).members()),path);
    	}
    	return null;
    }
	
	/**
	 * @return True if beginningSegments[i] == testSegments[i] for all 0<=i<beginningSegments[i] 
	 */
	private static boolean startsWith(String[] beginningSegments, String[] testSegments) { 
		for(int i=0; i < beginningSegments.length; i++) {
			if(!beginningSegments[i].equals(testSegments[i]))
				return false;
		}
		return true;
	}
	
	public static IFlatFolder ensureParentExists(List<IFlatResource> members, IPath path, IContainer cc) {
		IFlatFolder parent = (IFlatFolder) getExistingModuleResource(members, path);
		if (parent == null && path.segmentCount() > 0) {
			String folderName = path.lastSegment();
			IPath folderPath = Path.EMPTY;
			if (path.segmentCount()>1)
				folderPath = path.removeLastSegments(1);
			parent = new FlatFolder(cc, folderName, folderPath);
			if (path.segmentCount()>1)
				addMembersToModuleFolder(ensureParentExists(members, path.removeLastSegments(1),cc), new IFlatResource[] {parent});
			else
				members.add(parent);
		}
		return parent;
	}
	
	/**
	 * Add the resources from mr to the existing resources in Module Folder mf
	 * @param ModuleFolder mf
	 * @param IModuleResource[] mr
	 */
	public static void addMembersToModuleFolder(IFlatFolder mf, IFlatResource[] 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
		IFlatResource[] 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
		IFlatResource[] res = new FlatResource[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);
	}
	
}
