/*******************************************************************************
 * Copyright (c) 2001, 2007 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.commonarchivecore.internal.strategy;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.common.util.WrappedException;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.URIConverter;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.jem.internal.java.adapters.jdk.JavaJDKAdapterFactory;
import org.eclipse.jem.util.logger.proxy.Logger;
import org.eclipse.jst.j2ee.common.internal.impl.J2EEResouceFactorySaxRegistry;
import org.eclipse.jst.j2ee.common.internal.impl.J2EEResourceFactoryDomRegistry;
import org.eclipse.jst.j2ee.common.internal.impl.J2EEResourceFactoryRegistry;
import org.eclipse.jst.j2ee.commonarchivecore.internal.Archive;
import org.eclipse.jst.j2ee.commonarchivecore.internal.CommonArchiveFactoryRegistry;
import org.eclipse.jst.j2ee.commonarchivecore.internal.CommonArchiveResourceHandler;
import org.eclipse.jst.j2ee.commonarchivecore.internal.CommonarchiveFactory;
import org.eclipse.jst.j2ee.commonarchivecore.internal.Container;
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.OpenFailureException;
import org.eclipse.jst.j2ee.commonarchivecore.internal.exception.ResourceLoadException;
import org.eclipse.jst.j2ee.commonarchivecore.internal.helpers.ArchiveOptions;
import org.eclipse.jst.j2ee.commonarchivecore.internal.helpers.ArchiveURIConverterImpl;
import org.eclipse.jst.j2ee.commonarchivecore.internal.helpers.FileIterator;
import org.eclipse.jst.j2ee.commonarchivecore.internal.helpers.FileIteratorImpl;
import org.eclipse.jst.j2ee.commonarchivecore.internal.util.ArchiveUtil;
import org.eclipse.jst.j2ee.commonarchivecore.looseconfig.internal.LooseArchive;
import org.eclipse.jst.j2ee.commonarchivecore.looseconfig.internal.LooseConfigRegister;
import org.eclipse.wst.common.internal.emf.utilities.ExtendedEcoreUtil;

/**
 * Abstact implementer off which and load strategy may subclass
 * 
 * @see LoadStrategy
 */
public abstract class LoadStrategyImpl extends AdapterImpl implements LoadStrategy {

	/** flag to indicate whether underlying resources have been closed */
	protected boolean isOpen = true;

	/** The archive or directory to which this strategy belongs */
	protected Container container;

	/** ResourceSet used for mof/xmi resources */
	protected ResourceSet resourceSet;

	protected LooseArchive looseArchive;

	protected Map collectedLooseArchiveFiles = Collections.EMPTY_MAP;

	protected boolean readOnly = false;

	private int rendererType;

	public LoadStrategyImpl() {
		super();
	}

	/**
	 * @see Archive
	 */
	public void addOrReplaceMofResource(Resource aResource) {
		Resource existingResource = getResourceSet().getResource(aResource.getURI(), false);
		if (existingResource != null)
			getResourceSet().getResources().remove(existingResource);
		getResourceSet().getResources().add(aResource);
	}

	protected void updateModificationTracking(Resource res) {
		boolean trackingMods = res.isTrackingModification();
		boolean isReadOnly = (container != null) ? ((Archive) container).getOptions().isReadOnly() : false;
		boolean shouldTrackMods = !(isReadOnly || ArchiveUtil.isJavaResource(res) || ArchiveUtil.isRegisteredURIMapping(res));
		if (shouldTrackMods && !trackingMods)
			res.setTrackingModification(true);
	}

	/**
	 * Release any resources being held by this object and set the state to closed. Subclasses
	 * should override as necessary
	 */
	public void close() {
		setIsOpen(false);
        if(resourceSet != null && resourceSet.eAdapters().contains(this))
        	resourceSet.eAdapters().remove(this);

	}

	protected abstract boolean primContains(String uri);

	/**
	 * @see LoadStrategy
	 */
	public boolean contains(String uri) {
		if (containsUsingLooseArchive(uri))
			return true;
		return primContains(uri);
	}

	/*
	 * Try the resources path first; if that false, see if we have a child loose archive with the
	 * uri
	 */
	protected boolean containsUsingLooseArchive(String uri) {
		if (getLooseArchive() == null)
			return false;

		LooseArchive loose = getLooseArchive();
		if (loose.getResourcesPath() == null)
			return false;

		java.io.File aFile = new java.io.File(loose.getResourcesPath(), uri);
		if (aFile.exists())
			return true;

		return LooseConfigRegister.singleton().findFirstLooseChild(uri, loose) != null;
	}

	protected File createDirectory(String uri){
		File aFile = null;
		aFile = getArchiveFactory().createFile();
		aFile.setDirectoryEntry(true);
		aFile.setURI(uri);
		aFile.setOriginalURI(uri);
		aFile.setLoadingContainer(getContainer());
		return aFile;
	}
	
	protected File createFile(String uri) {
		File aFile = null;
		if (isArchive(uri))
			aFile = openNestedArchive(uri);
		if (aFile == null) {
			aFile = getArchiveFactory().createFile();
			aFile.setURI(uri);
			aFile.setOriginalURI(uri);
		}
		aFile.setLoadingContainer(getContainer());
		return aFile;
	}

	protected void finalize() throws Throwable {
		if(isOpen){
			close();
		}
	}

	/**
	 * @see LoadStrategy
	 */
	public java.lang.String getAbsolutePath() throws FileNotFoundException {
		throw new FileNotFoundException(CommonArchiveResourceHandler.Absolute_path_unknown_EXC_); // = "Absolute path unknown"
	}

	public String getResourcesPath() throws FileNotFoundException {
		return getLooseArchive() == null ? getAbsolutePath() : getLooseArchive().getResourcesPath();
	}

	protected String primGetResourcesPath() {
		return getLooseArchive() == null ? null : getLooseArchive().getResourcesPath();
	}

	public String getBinariesPath() throws FileNotFoundException {
		return getLooseArchive() == null ? getAbsolutePath() : getLooseArchive().getBinariesPath();
	}

	public CommonarchiveFactory getArchiveFactory() {
		return CommonArchiveFactoryRegistry.INSTANCE.getCommonArchiveFactory();
	}

	public Container getContainer() {
		return container;
	}

	public ResourceSet primGetResourceSet() {
		return resourceSet;
	}

	/**
	 * 
	 * Should we iterate all the files in the archive as part of saving, or can we treat the archive
	 * as one big file during save? The following rules apply, iterating the files if: 1) If the
	 * archive is a module file and it is NOT read-only 2) If the load strategy is a directory 3) If
	 * the archive is a utility JAR, and the files list has never been initialized, or if the
	 * loading containers for all the files are the same AND not directories, AND the
	 * {@link ArchiveOptions#isSaveLibrariesAsFiles()}of the archive is true.
	 * 
	 * @see com.ibm.etools.archive.LoadStrategy#requiresIterationOnSave()
	 */
	public boolean requiresIterationOnSave() {
		if (!getContainer().isArchive() || isDirectory())
			return true;
		Archive anArchive = (Archive) getContainer();
		//We should leave utility JARs intact, unless were told not to
		//The manifest may have been signed
		if (anArchive.isModuleFile())
			return !anArchive.getOptions().isReadOnly();
		else if (anArchive.getOptions().isSaveLibrariesAsFiles() && anArchive.getLoadingContainer() != null) {
			if (anArchive.isIndexed()) {
				List files = anArchive.getFiles();
				File aFile = null;
				Container firstContainer = null;
				Container lContainer = null;
				for (int i = 0; i < files.size(); i++) {
					aFile = (File) files.get(i);
					if (i == 0) {
						firstContainer = aFile.getLoadingContainer();
						if (firstContainer.getLoadStrategy().isDirectory())
							return true;
					}
					lContainer = aFile.getLoadingContainer();
					if (lContainer != firstContainer)
						return true;
				}
			}
			return false;
		} else
			return true;
	}

	public ResourceSet getResourceSet() {
		if (resourceSet == null) {
			initializeResourceSet();
			resourceSet.eAdapters().add(this);
		}
		return resourceSet;
	}

	/**
	 * @see org.eclipse.emf.common.notify.impl.AdapterImpl#notifyChanged(Notification)
	 */
	public void notifyChanged(Notification msg) {
		switch (msg.getEventType()) {
			case Notification.ADD :
				updateModificationTracking((Resource) msg.getNewValue());
				break;
			case Notification.ADD_MANY :
				List list = (List) msg.getNewValue();
				for (int i = 0; i < list.size(); i++) {
					updateModificationTracking((Resource) list.get(i));
				}
			default :
				break;
		}
	}

	/**
	 * Used internally; clients should not need to call
	 */
	public FileIterator getFileIterator() throws IOException {
		return new FileIteratorImpl(getContainer().getFiles());
	}

	/**
	 * @see com.ibm.etools.archive.LoadStrategy
	 */
	public abstract List getFiles();

	public List collectFiles() {
		//The loose archives need to be read first
		collectFilesFromLooseArchives();
		List files = getFiles();
		files.addAll(collectedLooseArchiveFiles.values());
		collectedLooseArchiveFiles = Collections.EMPTY_MAP;
		return files;
	}

	protected void collectFilesFromLooseArchives() {
		if (!canHaveLooseChildren() || getLooseArchive() == null) {
			collectedLooseArchiveFiles = Collections.EMPTY_MAP;
			return;
		}

		collectedLooseArchiveFiles = new HashMap();
		List children = LooseConfigRegister.singleton().getLooseChildren(getLooseArchive());

		for (int i = 0; i < children.size(); i++) {
			LooseArchive loose = (LooseArchive) children.get(i);
			String uri = loose.getUri();
			if (!collectedLooseArchiveFiles.containsKey(uri)) {
				Archive archive = openNestedArchive(loose);
				if (archive != null) {
					collectedLooseArchiveFiles.put(uri, archive);
					archive.setLoadingContainer(getContainer());
				}
			}
		}
	}

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

	public InputStream getResourceInputStream(String uri) throws IOException {
		return getResourceSet().getURIConverter().createInputStream(URI.createURI(uri));
	}

	/**
	 * @see com.ibm.etools.commonarchive.Archive returns an immutable collection of the loaded
	 *      resources in the resource set
	 */
	public Collection getLoadedMofResources() {
		Collection resources = getResourceSet().getResources();
		if (resources.isEmpty())
			return Collections.EMPTY_LIST;
		List copyResources = new ArrayList();
		copyResources.addAll(resources);
		
		List result = new ArrayList(copyResources.size());
		Iterator iter = copyResources.iterator();
		while (iter.hasNext()) {
			Resource res = (Resource) iter.next();
			if (res.isLoaded())
				result.add(res);
		}
		return result;
	}

	/**
	 * @see com.ibm.etools.commonarchive.Archive
	 */
	public Resource getMofResource(String uri) throws FileNotFoundException, ResourceLoadException {
		try {
			return getResourceSet().getResource(URI.createURI(uri), true);
		} catch (WrappedException wrapEx) {
			if ((ExtendedEcoreUtil.getFileNotFoundDetector().isFileNotFound(wrapEx))) {
				FileNotFoundException fileNotFoundEx = ExtendedEcoreUtil.getInnerFileNotFoundException(wrapEx);
				throw fileNotFoundEx;
			}
			throwResourceLoadException(uri, wrapEx);
			return null; //never happens - compiler expects it though
		}
	}

	protected void initializeResourceSet() {
		//Not the best design here, because a load strategy should only know
		// about
		//container; however, this method will only get called when the
		// container
		//is an archive
		Archive archive = (Archive) getContainer();
		URIConverter converter = new ArchiveURIConverterImpl(archive, primGetResourcesPath());
		ResourceSet rs = new ResourceSetImpl();
		Resource.Factory.Registry reg = createResourceFactoryRegistry();
		rs.setResourceFactoryRegistry(reg);
		setResourceSet(rs);
		rs.setURIConverter(converter);
		if (archive.shouldUseJavaReflection()) {
			rs.getAdapterFactories().add(new JavaJDKAdapterFactory());
			
			// TFB: Problem here:
			// 'Archive.initializeClassLoader' calls
			// 'Archive.getJavaAdapterFactory', which
			// 'Archive.getResourceSet', which calls
			// 'LoadStrategy.initializeResourceSet', which calls
			// 'Archive.initializeClassLoader' all over again.
			//
			// This creates a second, redundant classloader,
			// and places the first classloader in the JavaJDKAdapterFactory.
			// Hence not only is the classloader created twice, but
			// both copies are active.  When there are large classpaths,
			// this will large duplicate structures.
			//
			// Since the classloader will be initialized by 'getClassLoader',
			// the initialization, here, seems unnecessary.
			
			// archive.initializeClassLoader();
		}
	}

	protected Resource.Factory.Registry createResourceFactoryRegistry() {
		if (isReadOnly())
			return new J2EEResouceFactorySaxRegistry();

		Resource.Factory.Registry registry = null;
		switch (getRendererType()) {
			case ArchiveOptions.SAX :
				registry = new J2EEResouceFactorySaxRegistry();
				break;
			case ArchiveOptions.DOM :
				registry = new J2EEResourceFactoryDomRegistry();
				break;
			case ArchiveOptions.DEFAULT :
			default :
				registry = new J2EEResourceFactoryRegistry();
				break;
		}
		return registry;
	}

	/**
	 * @return
	 */
	public int getRendererType() {
		return rendererType;
	}

	protected boolean isArchive(String uri) {
		return ((Archive) getContainer()).isNestedArchive(uri);
	}

	/**
	 * An archive uses a custom class loader for java reflection within a mof resourceSet;
	 * implementers of LoadStrategy may supply a mof resourceSet for which this class loader is not
	 * necessary, or could even cause breakage; this test gives the strategy the chance to "opt out"
	 * of the class loading game
	 */
	public boolean isClassLoaderNeeded() {
		return true;
	}

	/**
	 * @see com.ibm.etools.archive.LoadStrategy The default is false
	 */
	public boolean isDirectory() {
		return false;
	}

	/**
	 * @see com.ibm.etools.archive.LoadStrategy#getExistingMofResource(String)
	 */
	public Resource getExistingMofResource(String uri) {
		return getResourceSet().getResource(URI.createURI(uri), false);
	}

	public boolean isMofResourceLoaded(java.lang.String uri) {
		Resource res = getExistingMofResource(uri);
		return res != null && res.isLoaded();
	}

	public boolean isOpen() {
		return isOpen;
	}

	/**
	 * @see com.ibm.etools.archive.LoadStrategy return false by default; subclasses should override
	 *      if necessary
	 */
	public boolean isUsing(java.io.File aSystemFile) {
		return false;
	}

	public Resource makeMofResource(String uri, EList extent) {
		Resource existing = getExistingMofResource(uri);
		if (existing != null)
			return existing;
		return getResourceSet().createResource(URI.createURI(uri));
	}

	protected Archive openNestedArchive(String uri) {

		try {
			return ((Archive) getContainer()).openNestedArchive(uri);
		} catch (OpenFailureException e) {
			//Caught an exception trying to open the nested archive
			Logger.getLogger().logError(e);
			return null;
		}

	}

	protected Archive openNestedArchive(LooseArchive loose) {

		try {
			return ((Archive) getContainer()).openNestedArchive(loose);
		} catch (OpenFailureException e) {
			//Caught an exception trying to open the nested archive
			Logger.getLogger().logError(e);
			return null;
		}

	}

	public void setContainer(Container newContainer) {
		container = newContainer;
	}

	public void setResourceSet(org.eclipse.emf.ecore.resource.ResourceSet newResourceSet) {
		// fixes problem in reopen
		if (resourceSet != newResourceSet) {

			// remove adapter from old resource set
			if (resourceSet != null)
				resourceSet.eAdapters().remove(this);

			// add as adapter to new resource set if necessary
			if (newResourceSet != null && !newResourceSet.eAdapters().contains(this))
				newResourceSet.eAdapters().add(this);

			resourceSet = newResourceSet;
		} // no need to update if old set equals new set (by reference)
	}

	protected void setIsOpen(boolean newIsOpen) {
		isOpen = newIsOpen;
	}

	protected void throwResourceLoadException(String resourceUri, Exception ex) throws ResourceLoadException {
		throw new ResourceLoadException(CommonArchiveResourceHandler.getString(CommonArchiveResourceHandler.load_resource_EXC_, (new Object[]{resourceUri, getContainer().getURI()})), ex); // = "Could not load resource "{0}" in archive "{1}""
	}

	/**
	 * Gets the looseArchive.
	 * 
	 * @return Returns a LooseArchive
	 */
	public LooseArchive getLooseArchive() {
		return looseArchive;
	}

	/**
	 * Sets the looseArchive.
	 * 
	 * @param looseArchive
	 *            The looseArchive to set
	 */
	public void setLooseArchive(LooseArchive looseArchive) {
		this.looseArchive = looseArchive;
		checkLoosePathsValid();
	}

	/*
	 * Added to support WAS runtime; throw an ArchiveRuntimeException if one of the paths in the
	 * loose config does not point to an existing file
	 */
	protected void checkLoosePathsValid() {
		if (looseArchive == null)
			return;

		String path = looseArchive.getBinariesPath();
		if (path != null) {
			java.io.File ioFile = new java.io.File(path);
			if (!ioFile.exists())
				throw new ArchiveRuntimeException("Invalid binaries path: " + path); //$NON-NLS-1$
		}
		path = looseArchive.getResourcesPath();
		if (path != null) {
			java.io.File ioFile = new java.io.File(path);
			if (!ioFile.exists())
				throw new ArchiveRuntimeException("Invalid resources path: " + path); //$NON-NLS-1$
		}
	}

	protected boolean canHaveLooseChildren() {
		return container.isEARFile() || container.isWARFile();
	}

	public boolean isReadOnly() {
		return readOnly;
	}

	public void setReadOnly(boolean readOnly) {
		this.readOnly = readOnly;
	}

	/**
	 * @param rendererType
	 *            The rendererType to set.
	 */
	public void setRendererType(int rendererType) {
		this.rendererType = rendererType;
	}
	
	public java.util.List getFiles(String subfolderPath) {
		List subset = new ArrayList();
		List theFiles = getFiles();
		for (int i = 0; i < theFiles.size(); i++) {
			File aFile = (File)theFiles.get(i);
			if (aFile.getURI().startsWith(subfolderPath))	
				subset.add(aFile);
		}
		return subset;
	}
}
