/*******************************************************************************
 * Copyright (c) 2003, 2004 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.archive.operations;



import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.eclipse.core.internal.resources.ProjectDescription;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IPath;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.URIConverter;
import org.eclipse.emf.ecore.resource.Resource.Factory.Registry;
import org.eclipse.jem.util.emf.workbench.JavaProjectUtilities;
import org.eclipse.jem.util.emf.workbench.WorkbenchURIConverter;
import org.eclipse.jem.util.emf.workbench.WorkbenchURIConverterImpl;
import org.eclipse.jst.j2ee.commonarchivecore.internal.File;
import org.eclipse.jst.j2ee.commonarchivecore.internal.exception.ArchiveRuntimeException;
import org.eclipse.jst.j2ee.commonarchivecore.internal.exception.SaveFailureException;
import org.eclipse.jst.j2ee.commonarchivecore.internal.strategy.LoadStrategyImpl;
import org.eclipse.jst.j2ee.commonarchivecore.internal.util.ArchiveUtil;
import org.eclipse.jst.j2ee.internal.common.impl.J2EEResourceFactoryRegistry;
import org.eclipse.wst.common.internal.emfworkbench.WorkbenchResourceHelper;

/**
 * Insert the type's description here. Creation date: (5/10/2001 3:54:51 PM)
 * 
 * @author: Administrator
 */
public abstract class J2EELoadStrategyImpl extends LoadStrategyImpl implements IJ2EEImportExportConstants {
	protected IProject project;
	protected ArrayList filesList;
	//This one is used for the dot files in the project
	protected WorkbenchURIConverter projectMetaURIConverter;
	protected WorkbenchURIConverter projectURIConverter;
	protected Set visitedURIs;
	private boolean exportSource = false;
	private boolean includeProjectMetaFiles = false;
	protected List sourceFolders;

	/**
	 * J2EELoadStrategyImpl constructor comment.
	 */
	public J2EELoadStrategyImpl() {
		super();
	}

	/**
	 * @see com.ibm.etools.archive.LoadStrategy
	 */
	public boolean contains(String uri) {

		if (projectURIConverter == null)
			getProjectURIConverter();
		return projectURIConverter.getFile(uri).exists();

	}

	/* should never get called outside of runtime */
	protected boolean primContains(String uri) {
		return false;
	}

	protected long getLastModified(IResource aResource) {
		return aResource.getLocation().toFile().lastModified();
	}

	/**
	 * @see com.ibm.etools.archive.LoadStrategy
	 */
	public java.util.List getFiles() {

		filesList.clear();
		try {

			List projMembers = Arrays.asList(project.members());
			List exopProjMembers = new ArrayList();
			Iterator iterator = projMembers.iterator();
			while (iterator.hasNext()) {
				exopProjMembers.add(iterator.next());
			}

			filesList = getFiles(exopProjMembers);

		} catch (Exception exc) {
			throw new ArchiveRuntimeException(EJBArchiveOpsResourceHandler.getString("ARCHIVE_OPERATION_FilesFromProject"), exc); //$NON-NLS-1$
			//$NON-NLS-1$
		}
		return filesList;
	}

	protected java.util.ArrayList getFiles(List projectResources) throws Exception {
		if (projectResources.isEmpty()) {
			return filesList;
		}

		IContainer outputFolder = JavaProjectUtilities.getJavaProjectOutputContainer(getProject());

		Iterator iterator = projectResources.iterator();
		while (iterator.hasNext()) {
			File cFile = null;
			IResource res = (IResource) (iterator.next());
			if ((res.getType() == IResource.FILE)) {

				//We have to avoid duplicates between the source and output folders (non-java
				// resources)
				IPath path = getOutputPathForFile(res.getProjectRelativePath());
				String uri = path == null ? null : path.toString();

				//Avoid adding files in source folder which are not in output folder.
				//unless they are .java or .sqlj (source)
				if (outputFolder != null && !outputFolder.exists(path)) {
					if (uri != null && !isSource(uri) && !uri.equals(ProjectDescription.DESCRIPTION_FILE_NAME) && !uri.equals(".classpath")) //$NON-NLS-1$
						continue;
				}

				if (uri == null)
					continue;
				if (!shouldInclude(uri)) //$NON-NLS-1$
					continue;
				if (getVisitedURIs().contains(uri))
					continue;
				cFile = createFile(uri);
				cFile.setLastModified(getLastModified(res));
				getVisitedURIs().add(uri);
				filesList.add(cFile);
			} else {
				if (shouldInclude((IContainer) res))
					getFiles(Arrays.asList(((IContainer) res).members()));
			}
		}
		return filesList;
	}

	protected boolean isSource(String uri) {
		if (uri == null)
			return false;
		return uri.endsWith(ArchiveUtil.DOT_JAVA) || uri.endsWith(ArchiveUtil.DOT_SQLJ);// ||
		// uri.equals(ProjectDescription.DESCRIPTION_FILE_NAME)
		// ||
		// uri.equals(".classpath");
	}

	protected boolean shouldInclude(IContainer iContainer) {
		return true;
	}

	protected boolean shouldInclude(String uri) {
		return isExportSource() || !isSource(uri);
	}

	/**
	 * @see com.ibm.etools.archive.LoadStrategy
	 */
	public java.io.InputStream getInputStream(String uri) throws IOException, FileNotFoundException {

		try {
			if (projectURIConverter == null)
				getProjectURIConverter();
			if (isProjectMetaFile(uri))
				return getProjectMetaURIConverter().createInputStream(URI.createURI(uri));
			return projectURIConverter.createInputStream(URI.createURI(uri));
		} catch (IOException e) {
			throw e;
		} catch (Exception e) {
			throw new ArchiveRuntimeException(e);
		}
	}

	protected boolean isProjectMetaFile(String uri) {
		return PROJECT_FILE_URI.equals(uri) || CLASSPATH_FILE_URI.equals(uri);
	}

	public abstract IContainer getModuleContainer();

	protected IPath getOutputPathForFile(IPath aPath) throws Exception {
		if (isProjectMetaFile(aPath.toString())) {
			if (includeProjectMetaFiles)
				return aPath;
			return null;
		}
		IContainer moduleContainer = getModuleContainer();
		IPath moduleContainerPath = moduleContainer.getProjectRelativePath();
		//check if the file is an output folder file
		if (aPath.segmentCount() > moduleContainerPath.segmentCount() && aPath.removeLastSegments(aPath.segmentCount() - moduleContainerPath.segmentCount()).equals(moduleContainerPath)) {
			IPath tempPath = aPath.removeFirstSegments(moduleContainerPath.segmentCount());
			if (moduleContainer.exists(tempPath)) {
				return tempPath;
			}
		}
		//if this file is in a source folder, find the source folder
		//and remove the source folder portion from the path
		List lSourceFolders = getSourceFolders();
		for (int i = 0; i < lSourceFolders.size(); i++) {
			IPath folderPath = ((IFolder) lSourceFolders.get(i)).getProjectRelativePath();
			if (aPath.segmentCount() > folderPath.segmentCount() && aPath.removeLastSegments(aPath.segmentCount() - folderPath.segmentCount()).equals(folderPath)) {
				return aPath.removeFirstSegments(folderPath.segmentCount());
			}
		}
		return null;
	}

	//		int charIndex = 0;

	//		ArrayList tokens = new ArrayList();
	//		String pathString = aPath.toString();
	//
	//		for (int i = 0; i < pathString.length(); i++) {
	//			if (pathString.charAt(i) == '/') {
	//				tokens.add(pathString.substring(charIndex, i));
	//				charIndex = ++i;
	//			}
	//		}

	//		int indexOfModule = -1;
	//		IContainer outputFolder = ProjectUtilities.getJavaProjectOutputContainer(getProject());
	// check if file is an output folder file

	//		if (tokens.contains(getModuleFolderName())) {
	//			indexOfModule = tokens.indexOf(getModuleFolderName());
	//			// make sure the path exists, if not, we should check source folders
	//			if (!outputFolder.exists(aPath.removeFirstSegments(indexOfModule + 1)))
	//				indexOfModule = -1;
	//		}
	// check if file is a source folder file
	//		if (indexOfModule == -1) {
	//			List localSourceFolders = getSourceFoldersNames();
	//			if (localSourceFolders != null) {
	//				for (int j = 0; j < localSourceFolders.size(); j++) {
	//					if (!tokens.isEmpty()) {
	//						if (((String) tokens.get(0)).equals(localSourceFolders.get(j))) {
	//							indexOfModule = tokens.indexOf(localSourceFolders.get(j));
	//							break;
	//						}
	//						continue;
	//					}
	//				}
	//			}
	//		}
	//		if (indexOfModule > -1)
	//			return aPath.removeFirstSegments(indexOfModule + 1);
	//		return null;
	//	}
	/**
	 * Insert the method's description here. Creation date: (7/19/2001 3:58:31 PM)
	 * 
	 * @return org.eclipse.core.resources.IProject
	 */
	public org.eclipse.core.resources.IProject getProject() {
		return project;
	}

	public abstract WorkbenchURIConverter getProjectURIConverter();

	public String getSourceFolderName() throws Exception {
		try {
			return JavaProjectUtilities.getSourceFolderOrFirst(project, null).getName();
		} catch (Exception e) {
			throw new SaveFailureException(EJBArchiveOpsResourceHandler.getString("ARCHIVE_OPERATION_ProjectNature"), e);//$NON-NLS-1$
		}

	}

	public List getSourceFoldersNames() throws Exception {
		try {
			List sourceFolderNames = new ArrayList();
			List localSourceFolders = getSourceFolders();
			for (int i = 0; i < localSourceFolders.size(); i++) {
				sourceFolderNames.add(((org.eclipse.core.resources.IFolder) localSourceFolders.get(i)).getName());
			}
			return sourceFolderNames;

		} catch (Exception e) {
			throw new SaveFailureException(EJBArchiveOpsResourceHandler.getString("ARCHIVE_OPERATION_ProjectNature"), e); //$NON-NLS-1$
		}
	}


	protected List getSourceFolders() {
		if (sourceFolders == null) {
			sourceFolders = JavaProjectUtilities.getSourceContainers(project);
		}
		return sourceFolders;
	}

	public Set getVisitedURIs() {
		if (visitedURIs == null)
			visitedURIs = new HashSet();
		return visitedURIs;
	}

	public boolean isClassLoaderNeeded() {
		return false;
	}

	/**
	 * Insert the method's description here. Creation date: (4/19/2001 6:07:54 PM)
	 * 
	 * @return boolean
	 */
	public boolean isExportSource() {
		return exportSource;
	}

	/**
	 * Insert the method's description here. Creation date: (4/19/2001 6:07:54 PM)
	 * 
	 * @param newExportSource
	 *            boolean
	 */
	public void setExportSource(boolean newExportSource) {
		exportSource = newExportSource;
	}

	/**
	 * Returns the includeProjectMetaFiles.
	 * 
	 * @return boolean
	 */
	public boolean shouldIncludeProjectMetaFiles() {
		return includeProjectMetaFiles;
	}


	/**
	 * Sets the includeProjectMetaFiles.
	 * 
	 * @param includeProjectMetaFiles
	 *            The includeProjectMetaFiles to set
	 */
	public void setIncludeProjectMetaFiles(boolean includeProjectMetaFiles) {
		this.includeProjectMetaFiles = includeProjectMetaFiles;
	}

	protected URIConverter getProjectMetaURIConverter() {
		if (projectMetaURIConverter == null)
			projectMetaURIConverter = new WorkbenchURIConverterImpl(getProject());
		return projectMetaURIConverter;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ibm.etools.archive.impl.LoadStrategyImpl#requiresIterationOnSave()
	 */
	public boolean requiresIterationOnSave() {
		return true;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.j2ee.internal.internal.commonarchivecore.strategy.LoadStrategyImpl#initializeResourceSet()
	 */
	protected void initializeResourceSet() {
		resourceSet = WorkbenchResourceHelper.getResourceSet(project);
	}

	/*
	 * Overrode from super to bypass SAX
	 */
	protected Registry createResourceFactoryRegistry() {
		return new J2EEResourceFactoryRegistry();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.j2ee.internal.internal.commonarchivecore.strategy.LoadStrategyImpl#getAbsolutePath()
	 */
	public String getAbsolutePath() throws FileNotFoundException {
		return project.getLocation().toOSString();
	}
}