/*******************************************************************************
 * Copyright (c) 2003, 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.internal.componentcore;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.jem.util.emf.workbench.WorkbenchResourceHelperBase;
import org.eclipse.jem.util.logger.proxy.Logger;
import org.eclipse.jst.j2ee.commonarchivecore.internal.Archive;
import org.eclipse.jst.j2ee.commonarchivecore.internal.CommonArchiveResourceHandler;
import org.eclipse.jst.j2ee.commonarchivecore.internal.CommonarchiveFactory;
import org.eclipse.jst.j2ee.commonarchivecore.internal.exception.OpenFailureException;
import org.eclipse.jst.j2ee.commonarchivecore.internal.helpers.ArchiveOptions;
import org.eclipse.jst.j2ee.commonarchivecore.internal.helpers.ArchiveTypeDiscriminator;
import org.eclipse.jst.j2ee.commonarchivecore.internal.strategy.ZipFileLoadStrategyImpl;
import org.eclipse.jst.j2ee.internal.project.J2EEProjectUtilities;
import org.eclipse.jst.jee.archive.internal.ArchiveUtil;
import org.eclipse.wst.common.componentcore.internal.BinaryComponentHelper;
import org.eclipse.wst.common.componentcore.internal.resources.VirtualArchiveComponent;
import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
import org.eclipse.wst.common.componentcore.resources.IVirtualReference;

/**
 * @deprecated see {@link JavaEEBinaryComponentHelper}
 * @author jasholl
 *
 */
public abstract class EnterpriseBinaryComponentHelper extends BinaryComponentHelper {

	public static EnterpriseBinaryComponentHelper getHelper(IVirtualComponent aComponent){
		EnterpriseBinaryComponentHelper helper = null;
		if (J2EEProjectUtilities.isEJBComponent(aComponent)) {
			helper = new EJBBinaryComponentHelper(aComponent);
		} else if (J2EEProjectUtilities.isApplicationClientComponent(aComponent)) {
			helper = new AppClientBinaryComponentHelper(aComponent);
		} else if (J2EEProjectUtilities.isJCAComponent(aComponent)) {
			helper = new JCABinaryComponentHelper(aComponent);
		} else if (J2EEProjectUtilities.isDynamicWebComponent(aComponent)) {
			helper = new WebBinaryComponentHelper(aComponent);
		} else {
			helper = new UtilityBinaryComponentHelper(aComponent);
		}
		return helper;
	}
	
	IReferenceCountedArchive archive = null;

	protected EnterpriseBinaryComponentHelper(IVirtualComponent component) {
		super(component);
	}

	protected ComponentArchiveOptions getArchiveOptions() {
		ComponentArchiveOptions options = new ComponentArchiveOptions(getComponent());
		options.setIsReadOnly(true);
		options.setRendererType(ArchiveOptions.SAX);
		options.setUseJavaReflection(false);
		return options;
	}

	protected IReferenceCountedArchive getUniqueArchive() {
		try {
			return openArchive();
		} catch (OpenFailureException e) {
			Logger.getLogger().logError(e);
		}
		return null;
	}

	public Archive accessArchive() {
		IReferenceCountedArchive archive = getArchive();
		archive.access();
		if(!isPhysicallyOpen(archive)){
			physicallyOpen(archive);
		}
		return archive;
	}

	protected IReferenceCountedArchive getArchive() {
		if (archive == null) {
			archive = getUniqueArchive();
		}
		return archive;
	}

	protected boolean isArchiveValid() {
		if (archive != null) {
			return true;
		}
		Archive anArchive = null;
		try {
			anArchive = CommonarchiveFactory.eINSTANCE.primOpenArchive(getArchiveOptions(), getArchiveURI());
			ArchiveTypeDiscriminator disc = getDiscriminator();
			return null == disc || disc.canImport(anArchive);
		} catch (Exception e) {
			return false;
		} finally {
			if (anArchive != null) {
				anArchive.close();
			}
		}
	}

	protected String getArchiveURI() {
		String archiveURI = null;
		VirtualArchiveComponent archiveComp = (VirtualArchiveComponent) getComponent();
		java.io.File diskFile = archiveComp.getUnderlyingDiskFile();
		if (diskFile.exists())
			archiveURI = diskFile.getAbsolutePath();
		else {
			IFile iFile = archiveComp.getUnderlyingWorkbenchFile();
			archiveURI = iFile.getRawLocation().toOSString();
		}
		return archiveURI;
	}

	public void dispose() {
		if (archive != null) {
			archive.close();
			archive = null;
		}
	}

	protected abstract ArchiveTypeDiscriminator getDiscriminator();

	protected IReferenceCountedArchive openArchive() throws OpenFailureException {
		ArchiveCache cache = ArchiveCache.getInstance();
		IReferenceCountedArchive archive = cache.getArchive(getComponent());
		if (archive != null) {
			archive.access();
			return archive;
		}
		return cache.openArchive(this);
	}

	boolean gotResource = false;
	
	public Resource getResource(URI uri) {
		Resource resource = null;
		if(!isPhysicallyOpen(getArchive())){
			resource = getArchive().getResourceSet().getResource(uri, false);
			if(resource == null){
				physicallyOpen(getArchive());
			}
		}
		if(resource == null){
			resource = getArchive().getResourceSet().getResource(uri, true); 
		}
		
		return resource;
	}

	public void releaseAccess() {
		dispose();
	}

	private static void unloadArchive(IReferenceCountedArchive archive) {
		WorkbenchResourceHelperBase.removeAndUnloadAll(archive.getResourceSet().getResources(), archive.getResourceSet());
		archive.getLoadStrategy().setResourceSet(null);
		archive.setLoadStrategy(null);
	}
	
	private static boolean isPhysicallyOpen(IReferenceCountedArchive archive) {
		return ((BinaryZipFileLoadStrategy)archive.getLoadStrategy()).isPhysicallyOpen();
	}
	
	private static void physicallyOpen(IReferenceCountedArchive archive) {
		try {
			((BinaryZipFileLoadStrategy)archive.getLoadStrategy()).physicallyOpen();
		} catch (ZipException e) {
			Logger.getLogger().logError(e);
		} catch (IOException e) {
			Logger.getLogger().logError(e);
		}
	}
	
	protected static void physicallyClose(IReferenceCountedArchive archive) {
		((BinaryZipFileLoadStrategy)archive.getLoadStrategy()).physicallyClose();
	}
	
	protected void aboutToClose() {
		//default is to do nothing
	}
	
	protected void preCleanupAfterTempSave(String uri, File original, File destinationFile) {
		//default is to do nothing
	}
	protected void postCleanupAfterTempSave(String uri, File original, File destinationFile) {
		//default is to do nothing
	}

	private static class BinaryZipFileLoadStrategy extends ZipFileLoadStrategyImpl {
		
		private boolean physicallyOpen = true;
		
		public BinaryZipFileLoadStrategy() {
			super();
		}

		public BinaryZipFileLoadStrategy(java.io.File file) throws IOException {
			super(file);
		}
		
		public void close() {
			physicallyOpen = false;
			super.close();
		}

		public boolean isPhysicallyOpen(){
			return physicallyOpen;
		}
		
		public void physicallyOpen() throws ZipException, IOException{
			if(!isPhysicallyOpen()){
				physicallyOpen = true;
				setZipFile(ArchiveUtil.newZipFile(file));
			}
		}
		
		public void physicallyClose(){
			if(isPhysicallyOpen()){
				physicallyOpen = false;
				try{
					zipFile.close();
				}
				catch (Throwable t) {
					//Ignore
				}
			} 
		}
		
		public InputStream getInputStream(String uri) throws IOException, FileNotFoundException {
			final boolean isPhysciallyOpen = isPhysicallyOpen();
			Exception caughtException = null;
			try {
				if (!isPhysciallyOpen) {
					physicallyOpen();
				}
				ZipEntry entry = getZipFile().getEntry(uri);
				if (entry == null)
					throw new FileNotFoundException(uri);

				return new java.io.BufferedInputStream(getZipFile().getInputStream(entry)) {
					public void close() throws IOException {
						super.close();
						if (!isPhysciallyOpen ) {
							physicallyClose();
						}
					}
				};
			} catch (FileNotFoundException e) {
				caughtException = e;
				throw e;
			} catch (IllegalStateException zipClosed) {
				caughtException = zipClosed;
				throw new IOException(zipClosed.toString());
			} catch (Exception e) {
				caughtException = e;
				throw new IOException(e.toString());
			} finally {
				if (caughtException != null) {
					if (!isPhysciallyOpen) {
						physicallyClose();
					}
				}
			}
		}
	};
	
	public static class ArchiveCache {

		private static ArchiveCache instance = null;

		public static ArchiveCache getInstance() {
			if (instance == null) {
				instance = new ArchiveCache();
			}
			return instance;
		}

		protected Map componentsToArchives = new Hashtable();

		public synchronized IReferenceCountedArchive getArchive(IVirtualComponent component) {
			IReferenceCountedArchive archive = (IReferenceCountedArchive) componentsToArchives.get(component);
			return archive;
		}

		public synchronized void clearDisconnectedArchivesInEAR(IVirtualComponent earComponent) {
			if (componentsToArchives.isEmpty()) {
				return;
			}
			Set liveBinaryComponnts = new HashSet();
			IVirtualReference[] refs = earComponent.getReferences();
			IVirtualComponent component = null;
			for (int i = 0; i < refs.length; i++) {
				component = refs[i].getReferencedComponent();
				if (component.isBinary()) {
					liveBinaryComponnts.add(component);
				}
			}
			clearArchivesInProject(earComponent.getProject(), liveBinaryComponnts);
		}

		public synchronized void clearAllArchivesInProject(IProject earProject) {
			if (componentsToArchives.isEmpty()) {
				return;
			}
			clearArchivesInProject(earProject, null);
		}

		private void clearArchivesInProject(IProject earProject, Set excludeSet) {
			Iterator iterator = componentsToArchives.entrySet().iterator();
			IVirtualComponent component = null;
			IReferenceCountedArchive archive = null;
			while (iterator.hasNext()) {
				Map.Entry entry = (Map.Entry)iterator.next();
				component = (IVirtualComponent) entry.getKey();
				if (component.getProject().equals(earProject) && (excludeSet == null || !excludeSet.contains(component))) {
					archive = (IReferenceCountedArchive) entry.getValue();
					archive.forceClose();
					unloadArchive(archive);
					iterator.remove();
				}
			}
		}

		public synchronized IReferenceCountedArchive openArchive(EnterpriseBinaryComponentHelper helper) throws OpenFailureException {
			ArchiveOptions options = helper.getArchiveOptions();
			String archiveURI = helper.getArchiveURI();
			
			options.setLoadStrategy(createBinaryLoadStrategy(helper));

			Archive anArchive = CommonarchiveFactory.eINSTANCE.primOpenArchive(options, archiveURI);

			ArchiveTypeDiscriminator discriminator = helper.getDiscriminator();

			if (!discriminator.canImport(anArchive)) {
				anArchive.close();
				throw new OpenFailureException(discriminator.getUnableToOpenMessage());
			}
			IReferenceCountedArchive specificArchive = (IReferenceCountedArchive) discriminator.openArchive(anArchive);
			specificArchive.setEnterpriseBinaryComponentHelper(helper);
			specificArchive.initializeAfterOpen();
			specificArchive.access();
			componentsToArchives.put(helper.getComponent(), specificArchive);
			return specificArchive;
		}
	}
	
	protected static BinaryZipFileLoadStrategy createBinaryLoadStrategy(EnterpriseBinaryComponentHelper helper) throws OpenFailureException {
		String archiveURI = helper.getArchiveURI();
		String filename = archiveURI.replace('/', java.io.File.separatorChar);
		java.io.File file = new java.io.File(filename);
		if (!file.exists()) {
			throw new OpenFailureException(CommonArchiveResourceHandler.getString(CommonArchiveResourceHandler.file_not_found_EXC_, (new Object[] { archiveURI, file.getAbsolutePath() }))); 
		}
		try {
			BinaryZipFileLoadStrategy strategy = new BinaryZipFileLoadStrategy(file);
			return strategy;
		} catch (IOException ex) {
			throw new OpenFailureException(CommonArchiveResourceHandler.getString(CommonArchiveResourceHandler.could_not_open_EXC_, (new Object[] { archiveURI })), ex); 
		}
	}

	protected interface IReferenceCountedArchive extends Archive {

		/**
		 * Increases the reference count by one. A call to close will decriment
		 * the count by one. If after decrimenting the count the count is 0
		 * 
		 */
		public void access();

		public void forceClose();
		
		public void setEnterpriseBinaryComponentHelper(EnterpriseBinaryComponentHelper helper);
		
		public EnterpriseBinaryComponentHelper getEnterpriseBinaryComponentHelper();
		
	}

}
