package org.eclipse.jst.j2ee.internal.componentcore;

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

import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.jst.j2ee.commonarchivecore.internal.Archive;
import org.eclipse.jst.j2ee.internal.J2EEConstants;
import org.eclipse.jst.j2ee.internal.archive.JavaEEArchiveUtilities;
import org.eclipse.jst.j2ee.internal.componentcore.EnterpriseBinaryComponentHelper.IReferenceCountedArchive;
import org.eclipse.jst.j2ee.internal.plugin.J2EEPlugin;
import org.eclipse.jst.javaee.applicationclient.ApplicationClient;
import org.eclipse.jst.javaee.applicationclient.ApplicationclientFactory;
import org.eclipse.jst.javaee.core.DisplayName;
import org.eclipse.jst.javaee.core.JavaeeFactory;
import org.eclipse.jst.javaee.ejb.EJBJar;
import org.eclipse.jst.javaee.ejb.EjbFactory;
import org.eclipse.jst.javaee.web.WebApp;
import org.eclipse.jst.javaee.web.WebFactory;
import org.eclipse.jst.jee.archive.ArchiveModelLoadException;
import org.eclipse.jst.jee.archive.ArchiveOpenFailureException;
import org.eclipse.jst.jee.archive.ArchiveOptions;
import org.eclipse.jst.jee.archive.IArchive;
import org.eclipse.jst.jee.archive.IArchiveFactory;
import org.eclipse.jst.jee.archive.IArchiveLoadAdapter;
import org.eclipse.jst.jee.archive.internal.ArchiveFactoryImpl;
import org.eclipse.jst.jee.util.internal.JavaEEQuickPeek;
import org.eclipse.wst.common.componentcore.ComponentCore;
import org.eclipse.wst.common.componentcore.internal.BinaryComponentHelper;
import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
import org.eclipse.wst.common.componentcore.resources.IVirtualReference;

public class JavaEEBinaryComponentHelper extends BinaryComponentHelper {

	private IArchive archive;
	private EnterpriseBinaryComponentHelper legacyBinaryHelper;
	private boolean descriminateMainClass = true;
	private int localArchiveAccessCount = 0;

	public static JavaEEQuickPeek getJavaEEQuickPeek(IPath filesystemPath) {
		IArchive archive = null; 
		try {
			try {
				archive = JavaEEArchiveUtilities.INSTANCE.openArchive(filesystemPath);
			} catch( ArchiveOpenFailureException fail) {}
			if (archive == null) {
				return new JavaEEQuickPeek(null);
			}
			JavaEEQuickPeek qp = JavaEEArchiveUtilities.INSTANCE.getJavaEEQuickPeek(archive);
			return qp;
		} finally {
			if (null != archive) {
				new ArchiveFactoryImpl().closeArchive(archive);
			}
		}
	}
	
	public static JavaEEQuickPeek getJavaEEQuickPeek(IVirtualComponent aBinaryComponent) {
		JavaEEBinaryComponentHelper helper = null;
		try {
			helper = new JavaEEBinaryComponentHelper(aBinaryComponent);
			IArchive archive = helper.getArchive();
			if (archive == null) {
				return new JavaEEQuickPeek(null);
			}
			JavaEEQuickPeek qp = JavaEEArchiveUtilities.INSTANCE.getJavaEEQuickPeek(archive);
			return qp;
		} finally {
			if (helper != null) {
				helper.dispose();
			}
		}
	}
	
	public static void openArchive(IVirtualComponent aBinaryComponent, boolean descriminateMainClass) {
		JavaEEBinaryComponentHelper helper = null;
		try {
			helper = new JavaEEBinaryComponentHelper(aBinaryComponent);
			helper.setDescriminateMainClass(descriminateMainClass);
			try {
				helper.openArchive();
			} catch (ArchiveOpenFailureException e) {
				J2EEPlugin.logError(e);
			}
		} finally {
			if (helper != null) {
				helper.dispose();
			}
		}
	}

	public JavaEEBinaryComponentHelper(IVirtualComponent aBinaryComponent) {
		super(aBinaryComponent);
	}

	public IPath getAbsolutePath() {
		IArchiveLoadAdapter loadAdapter = null;
		if(getArchive().getArchiveOptions().hasOption(JavaEEArchiveUtilities.WRAPPED_LOAD_ADAPTER)){
			loadAdapter = (IArchiveLoadAdapter)getArchive().getArchiveOptions().getOption(JavaEEArchiveUtilities.WRAPPED_LOAD_ADAPTER);
		} else {
			loadAdapter = (IArchiveLoadAdapter)getArchive().getArchiveOptions().getOption(ArchiveOptions.LOAD_ADAPTER);
		}
		return ((JavaEEBinaryComponentLoadAdapter) loadAdapter).getArchivePath();
	}
	
	@Override
	public EObject getPrimaryRootObject() {
		JavaEEQuickPeek qp = JavaEEArchiveUtilities.INSTANCE.getJavaEEQuickPeek(getArchive());
		IPath ddPath = null;
		switch (qp.getType()) {
		case JavaEEQuickPeek.APPLICATION_CLIENT_TYPE:
			ddPath = new Path(J2EEConstants.APP_CLIENT_DD_URI);
			break;
		case JavaEEQuickPeek.EJB_TYPE:
			ddPath = new Path(J2EEConstants.EJBJAR_DD_URI);
			break;
		case JavaEEQuickPeek.WEB_TYPE:
			ddPath = new Path(J2EEConstants.WEBAPP_DD_URI);
			break;
		case JavaEEQuickPeek.CONNECTOR_TYPE:
			ddPath = new Path(J2EEConstants.RAR_DD_URI);
			break;
		case JavaEEQuickPeek.WEBFRAGMENT_TYPE:
			ddPath = new Path(J2EEConstants.WEBFRAGMENT_DD_URI);
			break;
		}
		if (ddPath != null) {
			if (getArchive().containsArchiveResource(ddPath)) {
				try {
					return (EObject) getArchive().getModelObject(ddPath);
				} catch (ArchiveModelLoadException e) {
					J2EEPlugin.logError(e);
				}
			} else {
				String displayName = getComponent().getName();
				//because this component is binary, its project must be the EAR.
				IVirtualComponent earComponent = ComponentCore.createComponent(getComponent().getProject());
				IVirtualReference [] refs = earComponent.getReferences();
				for(IVirtualReference ref:refs){
					if(ref.getReferencedComponent().equals(getComponent())){
						displayName = ref.getArchiveName();
						break;
					}
				}
				DisplayName dn = JavaeeFactory.eINSTANCE.createDisplayName();
				dn.setValue(displayName);
				EObject root = null;
				switch (qp.getType()) {
				case JavaEEQuickPeek.APPLICATION_CLIENT_TYPE:
					ApplicationClient applicationClient = ApplicationclientFactory.eINSTANCE.createApplicationClient();
					applicationClient.getDisplayNames().add(dn);
					root = (EObject) applicationClient;
					break;
				case JavaEEQuickPeek.EJB_TYPE:
					EJBJar ejbJar = EjbFactory.eINSTANCE.createEJBJar();
					ejbJar.getDisplayNames().add(dn);
					root = (EObject) ejbJar;
					break;
				case JavaEEQuickPeek.WEB_TYPE:
					WebApp webApp = WebFactory.eINSTANCE.createWebApp();
					webApp.getDisplayNames().add(dn);
					root = (EObject) webApp;
					break;
				}
				return root;
			}
		}
		return null;
	}

	@Override
	public Resource getResource(URI uri) {
		IPath path = new Path(uri.toString());
		try {
			IArchiveLoadAdapter loadAdapter = null;
			if(getArchive().getArchiveOptions().hasOption(JavaEEArchiveUtilities.WRAPPED_LOAD_ADAPTER)){
				loadAdapter = (IArchiveLoadAdapter)getArchive().getArchiveOptions().getOption(JavaEEArchiveUtilities.WRAPPED_LOAD_ADAPTER);
			} else {
				loadAdapter = (IArchiveLoadAdapter)getArchive().getArchiveOptions().getOption(ArchiveOptions.LOAD_ADAPTER);
			}
			EObject modelRoot = (EObject)((JavaEEBinaryComponentLoadAdapter) loadAdapter).getModelObject(path); 
			return modelRoot.eResource();
		} catch (ArchiveModelLoadException e) {
			J2EEPlugin.logError(e);
		}
		return null;
	}

	public IArchive accessArchive() {
		IArchive archive = getArchive();
		if (null != archive) {
			ArchiveCache cache = ArchiveCache.getInstance();
			cache.accessArchive(archive);
			synchronized (this) {
				localArchiveAccessCount++;
			}
		}
		return archive;
	}
	
	protected void safeReleaseArchive(IArchive archive){
		int count = 0;
		synchronized(this){
			count = localArchiveAccessCount;
		}
		if(count > 0){
			releaseArchive(archive);
		}
	}

	public void releaseArchive(IArchive archive) {
		if (archive != this.archive) {
			throw new RuntimeException("The IArchive parameter must be the same IArchive retrieved from accessArchive"); //$NON-NLS-1$
		}
		if (null != archive) {
			ArchiveCache cache = ArchiveCache.getInstance();
			cache.releaseArchive(archive);
			synchronized (this) {
				localArchiveAccessCount--;
			}
		}
	}

	private int preSwapAccessCount = 0;
	protected void preFileSwap(){
		int count = 0;
		synchronized (this) {
			preSwapAccessCount = localArchiveAccessCount;
			count = preSwapAccessCount;
		}
		while (count > 0){
			count --;
			releaseArchive(archive);
		}
	}
	
	protected void postFileSwap() {
		int count = 0;
		synchronized (this) {
			count = preSwapAccessCount;
			preSwapAccessCount = 0;
		}
		while(count > 0){
			count --;
			accessArchive();
		}
	}
	
	public Archive accessLegacyArchive() {
		if(legacyBinaryHelper == null){
			JavaEEQuickPeek qp = getJavaEEQuickPeek(getComponent());
			switch (qp.getType()) {
			case JavaEEQuickPeek.APPLICATION_CLIENT_TYPE:
				legacyBinaryHelper = new AppClientBinaryComponentHelper(getComponent()){
					@Override
					protected void aboutToClose() {
						safeReleaseArchive(JavaEEBinaryComponentHelper.this.archive);
					}
					@Override
					protected void preCleanupAfterTempSave(String uri, File original, File destinationFile) {
						preFileSwap();
					}
					@Override
					protected void postCleanupAfterTempSave(String uri, File original, File destinationFile) {
						postFileSwap();
					}
				};
				break;
			case JavaEEQuickPeek.EJB_TYPE:
				legacyBinaryHelper = new EJBBinaryComponentHelper(getComponent()){
					@Override
					protected void aboutToClose() {
						safeReleaseArchive(JavaEEBinaryComponentHelper.this.archive);
					}
					@Override
					protected void preCleanupAfterTempSave(String uri, File original, File destinationFile) {
						preFileSwap();
					}
					@Override
					protected void postCleanupAfterTempSave(String uri, File original, File destinationFile) {
						postFileSwap();
					}
				};
				break;
			case JavaEEQuickPeek.WEB_TYPE:
				legacyBinaryHelper = new WebBinaryComponentHelper(getComponent()){
					@Override
					protected void aboutToClose() {
						safeReleaseArchive(JavaEEBinaryComponentHelper.this.archive);
					}
					@Override
					protected void preCleanupAfterTempSave(String uri, File original, File destinationFile) {
						preFileSwap();
					}
					@Override
					protected void postCleanupAfterTempSave(String uri, File original, File destinationFile) {
						postFileSwap();
					}
				};
				break;
			case JavaEEQuickPeek.CONNECTOR_TYPE:
				legacyBinaryHelper = new JCABinaryComponentHelper(getComponent()){
					@Override
					protected void aboutToClose() {
						safeReleaseArchive(JavaEEBinaryComponentHelper.this.archive);
					}
					@Override
					protected void preCleanupAfterTempSave(String uri, File original, File destinationFile) {
						preFileSwap();
					}
					@Override
					protected void postCleanupAfterTempSave(String uri, File original, File destinationFile) {
						postFileSwap();
					}
				};
				break;
			default: //utility jar
				legacyBinaryHelper = new UtilityBinaryComponentHelper(getComponent()){
					@Override
					protected void aboutToClose() {
						safeReleaseArchive(JavaEEBinaryComponentHelper.this.archive);
					}
					@Override
					protected void preCleanupAfterTempSave(String uri, File original, File destinationFile) {
						preFileSwap();
					}
					@Override
					protected void postCleanupAfterTempSave(String uri, File original, File destinationFile) {
						postFileSwap();
					}
				};
				break;
			}
		}
		accessArchive();
		Archive legacyArchive = legacyBinaryHelper.accessArchive();
		return legacyArchive;
	}
	
	@Override
	public void dispose() {
		super.dispose();
		int count = 0;
		synchronized (this) {
			count = localArchiveAccessCount;
		}
		if (count > 0 && archive != null) {
			ArchiveCache cache = ArchiveCache.getInstance();
			for (int i = 0; i < count; i++) {
				cache.releaseArchive(archive);
				synchronized (this) {
					localArchiveAccessCount--;
				}
			}
		}
		if(legacyBinaryHelper != null){
			IReferenceCountedArchive legacyArchive = legacyBinaryHelper.archive;
			if(legacyArchive != null){
				legacyArchive.forceClose();
			}
		}
	}

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

	protected IArchive getUniqueArchive() {
		try {
			return openArchive();
		} catch (ArchiveOpenFailureException e) {
			J2EEPlugin.logError(e);
		}
		return null;
	}

	protected IArchive openArchive() throws ArchiveOpenFailureException {
		ArchiveCache cache = ArchiveCache.getInstance();
		IArchive archive = cache.getArchive(getComponent());
		if (archive == null) {
			archive = cache.openArchive(this);
		}
		if (archive != null) {
			cache.accessArchive(archive);
			synchronized (this) {
				localArchiveAccessCount++;
			}
		}
		return archive;
	}

	public static void clearDisconnectedArchivesInEAR(IVirtualComponent earComponent) {
		ArchiveCache.getInstance().clearDisconnectedArchivesInEAR(earComponent);
	}

	public static void clearAllArchivesInProject(IProject earProject) {
		ArchiveCache.getInstance().clearAllArchivesInProject(earProject);
	}

	public void setDescriminateMainClass(boolean archiveOption) {
		descriminateMainClass = archiveOption;
	}

	public boolean shouldDescriminateMainClass() {
		return descriminateMainClass;
	}

	/**
	 * This cache manages IArchives across all
	 * {@link JavaEEBinaryComponentHelper} instances. If multiple
	 * {@link JavaEEBinaryComponentHelper} instances exist for the same
	 * underlying archive file (e.g. a jar file on disk) all will use the exact
	 * same IArchive instance. Care needs to be taken in managing the opening
	 * and closing of this IArchive which should only be done through internal
	 * methods within {@link JavaEEBinaryComponentHelper}
	 */
	private static class ArchiveCache {

		private static class ArchiveCacheInstanceHolder {
			private static ArchiveCache instance = new ArchiveCache();
		}

		public static ArchiveCache getInstance() {
			return ArchiveCacheInstanceHolder.instance;
		}

		protected Map<IVirtualComponent, IArchive> componentsToArchives = new Hashtable<IVirtualComponent, IArchive>();

		protected Map<IArchive, Integer> archiveAccessCount = new Hashtable<IArchive, Integer>();

		public synchronized void accessArchive(IArchive archive) {
			Integer count = archiveAccessCount.get(archive);
			if(count != null) {
				Integer newCount = new Integer(count.intValue() + 1);
				archiveAccessCount.put(archive, newCount);
				if (newCount.intValue() == 1) {
					JavaEEBinaryComponentLoadAdapter binaryAdapter = null;
					if (archive.getArchiveOptions().hasOption(JavaEEArchiveUtilities.WRAPPED_LOAD_ADAPTER)) {
						binaryAdapter = (JavaEEBinaryComponentLoadAdapter) archive.getArchiveOptions().getOption(JavaEEArchiveUtilities.WRAPPED_LOAD_ADAPTER);
					} else {
						binaryAdapter = (JavaEEBinaryComponentLoadAdapter) archive.getArchiveOptions().getOption(ArchiveOptions.LOAD_ADAPTER);
					}
					if (!binaryAdapter.isPhysicallyOpen()) {
						try {
							binaryAdapter.physicallyOpen();
						} catch (ZipException e) {
							org.eclipse.jst.j2ee.internal.plugin.J2EEPlugin.logError(e);
						} catch (IOException e) {
							org.eclipse.jst.j2ee.internal.plugin.J2EEPlugin.logError(e);
						}
					}
				}
			}
		}

		public synchronized void releaseArchive(IArchive archive) {
			Integer count = archiveAccessCount.get(archive);
			if(count != null) {
				Integer newCount = new Integer(count.intValue() - 1);
				archiveAccessCount.put(archive, newCount);
				if (newCount.intValue() == 0) {
					JavaEEBinaryComponentLoadAdapter binaryAdapter = null;
					if (archive.getArchiveOptions().hasOption(JavaEEArchiveUtilities.WRAPPED_LOAD_ADAPTER)) {
						binaryAdapter = (JavaEEBinaryComponentLoadAdapter) archive.getArchiveOptions().getOption(JavaEEArchiveUtilities.WRAPPED_LOAD_ADAPTER);
					} else {
						binaryAdapter = (JavaEEBinaryComponentLoadAdapter) archive.getArchiveOptions().getOption(ArchiveOptions.LOAD_ADAPTER);
					}
					if (binaryAdapter.isPhysicallyOpen()) {
						binaryAdapter.physicallyClose();
					}
				}
			}
		}

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

		public synchronized void clearDisconnectedArchivesInEAR(IVirtualComponent earComponent) {
			if (componentsToArchives.isEmpty()) {
				return;
			}
			Set<IVirtualComponent> liveBinaryComponnts = new HashSet<IVirtualComponent>();
			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;
			IArchive 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 = (IArchive) entry.getValue();
					IArchiveFactory.INSTANCE.closeArchive(archive);
					iterator.remove();
					archiveAccessCount.remove(archive);
				}
			}
		}

		public synchronized IArchive openArchive(JavaEEBinaryComponentHelper helper) throws ArchiveOpenFailureException {
			IArchive archive;
			if (helper.getComponent().isBinary()) {
				archive = JavaEEArchiveUtilities.INSTANCE.openBinaryArchive(helper.getComponent(), helper.shouldDescriminateMainClass());
			}
			else {
				archive = JavaEEArchiveUtilities.INSTANCE.openArchive(helper.getComponent());
			}
			componentsToArchives.put(helper.getComponent(), archive);
			archiveAccessCount.put(archive, new Integer(0));
			return archive;
		}
	}

}

