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

import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.jem.util.logger.proxy.Logger;
import org.eclipse.jst.j2ee.application.WebModule;
import org.eclipse.jst.j2ee.commonarchivecore.internal.Archive;
import org.eclipse.jst.j2ee.commonarchivecore.internal.EARFile;
import org.eclipse.jst.j2ee.commonarchivecore.internal.EJBJarFile;
import org.eclipse.jst.j2ee.commonarchivecore.internal.ModuleFile;
import org.eclipse.jst.j2ee.commonarchivecore.internal.WARFile;
import org.eclipse.jst.j2ee.commonarchivecore.internal.impl.FileImpl;
import org.eclipse.jst.j2ee.commonarchivecore.internal.util.ArchiveUtil;
import org.eclipse.jst.j2ee.ejb.EJBJar;
import org.eclipse.jst.j2ee.internal.J2EEConstants;
import org.eclipse.jst.j2ee.internal.J2EEVersionConstants;
import org.eclipse.jst.j2ee.internal.archive.operations.EARArchiveOpsResourceHandler;
import org.eclipse.jst.javaee.application.Application;
import org.eclipse.jst.javaee.application.Module;
import org.eclipse.jst.jee.archive.ArchiveModelLoadException;
import org.eclipse.jst.jee.archive.ArchiveOpenFailureException;
import org.eclipse.jst.jee.archive.IArchive;
import org.eclipse.jst.jee.archive.IArchiveResource;
import org.eclipse.jst.jee.util.internal.JavaEEQuickPeek;

public class ArchiveWrapper {

	//TODO remove commonArchive; possibly remove this entire class and
	//code directly to IArchive
	private Archive commonArchive = null;
	private IArchive archive = null;
	private JavaEEQuickPeek jqp = null;

	public ArchiveWrapper(IArchive archive) {
		this.archive = archive;
		JavaEEArchiveUtilities jea = JavaEEArchiveUtilities.INSTANCE;
		jqp = jea.getJavaEEQuickPeek(archive);
	}

	public ArchiveWrapper(Archive mFile) {
		this.commonArchive = mFile;
		int type = J2EEConstants.UNKNOWN;

		if (mFile.isApplicationClientFile()) {
			type = J2EEConstants.APPLICATION_CLIENT_TYPE;
		} else if (mFile.isEARFile()) {
			type = J2EEConstants.APPLICATION_TYPE;
		} else if (mFile.isEJBJarFile()) {
			type = J2EEConstants.EJB_TYPE;
		} else if (mFile.isWARFile()) {
			type = J2EEConstants.WEB_TYPE;
		} else if (mFile.isRARFile()) {
			type = J2EEConstants.CONNECTOR_TYPE;
		}
		if (type != J2EEConstants.UNKNOWN) {
			int version = ArchiveUtil.getFastSpecVersion((ModuleFile) mFile);
			jqp = new JavaEEQuickPeek(type, version);
		} else {
			jqp = new JavaEEQuickPeek(null);
		}
	}

	public JavaEEQuickPeek getJavaEEQuickPeek() {
		return jqp;
	}

	public Archive getCommonArchive() {
		return (Archive) commonArchive;
	}

	public Object getUnderLyingArchive() {
		if (archive != null) {
			return archive;
		}
		if (commonArchive != null) {
			return commonArchive;
		}
		fail();
		return null;
	}

	private ArchiveWrapper cachedParent = null;

	public ArchiveWrapper getParent() {
		if (null != cachedParent) {
			return cachedParent;
		}
		if (archive != null) {
			cachedParent = new ArchiveWrapper(archive.getArchive());
			return cachedParent;
		}
		if (commonArchive != null) {
			cachedParent = new ArchiveWrapper((Archive) commonArchive.eContainer());
			return cachedParent;
		}
		fail();
		return null;
	}

	public IArchive getIArchive() {
		return archive;
	}

	public void close() {
		try {
			if (commonArchive != null) {
				commonArchive.close();
			}
			if (archive != null) {
				JavaEEArchiveUtilities.INSTANCE.closeArchive(archive);
			}
		} catch (RuntimeException e) {
			Logger.getLogger().logError(e);
			throw e;
		}
	}

	public IPath getPath() {
		if (commonArchive != null) {
			IPath path = new Path(commonArchive.getURI());
			return path;
		}
		if (archive != null) {
			return archive.getPath();
		}
		fail();
		return null;
	}

	private void fail() {
		throw new RuntimeException("ArchiveWrapper is inconsistent.");
	}

	public int getSize() {
		if (commonArchive != null)
			return commonArchive.getFiles().size();
		else
			return archive.getArchiveResources().size();
	}

	private List<ArchiveWrapper> cachedWebLibs;

	public List<ArchiveWrapper> getWebLibs() {
		if (cachedWebLibs != null) {
			return cachedWebLibs;
		}
		if (jqp.getType() != J2EEVersionConstants.WEB_TYPE) {
			fail();
		}

		cachedWebLibs = new ArrayList<ArchiveWrapper>();

		if (commonArchive != null) {
			WARFile war = (WARFile) commonArchive;
			List libs = war.getLibArchives();
			for (int i = 0; i < libs.size(); i++) {
				cachedWebLibs.add(new ArchiveWrapper((Archive) libs.get(i)));
			}
			return cachedWebLibs;
		}
		if (archive != null) {
			List<IArchiveResource> resources = archive.getArchiveResources();
			for (IArchiveResource resource : resources) {
				if (resource.getType() != IArchiveResource.DIRECTORY_TYPE) {
					IPath path = resource.getPath();
					if (path.segmentCount() > 2) {
						if (path.segment(0).equals("WEB-INF") && path.segment(1).equals("lib")) {
							String lastSegment = path.lastSegment();
							if (lastSegment.endsWith("jar") || lastSegment.endsWith("zip")) {
								IArchive webLib;
								try {
									webLib = archive.getNestedArchive(resource);
									cachedWebLibs.add(new ArchiveWrapper(webLib));
								} catch (ArchiveOpenFailureException e) {
									Logger.getLogger().logError(e);
								}
							}
						}
					}
				}
			}
			return cachedWebLibs;
		}
		fail();
		return null;
	}

	private List <String>cachedDDMappedModuleURIs = null;
	
	public List<String> getDDMappedModuleURIs() {
		if(cachedDDMappedModuleURIs != null){
			return cachedDDMappedModuleURIs;
		}
		if (jqp.getType() != J2EEVersionConstants.APPLICATION_TYPE) {
			fail();
		}
		
		cachedDDMappedModuleURIs = new ArrayList<String>();
		
		if (commonArchive != null) {
			EARFile ear = (EARFile) commonArchive;
			List earMods = ear.getModuleFiles();
			for (int i = 0; i < earMods.size(); i++) {
				cachedDDMappedModuleURIs.add(((Archive) earMods.get(i)).getURI());
			}
			return cachedDDMappedModuleURIs;
		} else if(archive != null) {
			if(archive.containsArchiveResource(new Path(J2EEConstants.APPLICATION_DD_URI))){
				if(jqp.getJavaEEVersion() == JavaEEQuickPeek.JEE_5_0_ID){
					try {
						Application application = (Application) archive.getModelObject();
						List modules = application.getModules();
						for(int i=0;i<modules.size();i++){
							Module module = (Module)modules.get(i);
							String uri = module.getUri();
							cachedDDMappedModuleURIs.add(uri);
						}
					} catch (ArchiveModelLoadException e) {
						Logger.getLogger().logError(e);
					}
				} else { 
					try{
						org.eclipse.jst.j2ee.application.Application application = (org.eclipse.jst.j2ee.application.Application)archive.getModelObject();
						List modules = application.getModules();
						for(int i=0;i<modules.size();i++){
							org.eclipse.jst.j2ee.application.Module module = (org.eclipse.jst.j2ee.application.Module)modules.get(i);
							String uri = module.getUri();
							cachedDDMappedModuleURIs.add(uri);
						}
					}catch (ArchiveModelLoadException e) {
						Logger.getLogger().logError(e);
					}
				}
			}
		}
		return cachedDDMappedModuleURIs;
	}
	
	
	private List<ArchiveWrapper> cachedEARModules;

	public List<ArchiveWrapper> getEarModules() {
		if (cachedEARModules != null) {
			return cachedEARModules;
		}
		if (jqp.getType() != J2EEVersionConstants.APPLICATION_TYPE) {
			fail();
		}
		cachedEARModules = new ArrayList<ArchiveWrapper>();

		if (commonArchive != null) {
			EARFile ear = (EARFile) commonArchive;
			List earMods = ear.getModuleFiles();
			for (int i = 0; i < earMods.size(); i++) {
				cachedEARModules.add(new ArchiveWrapper((Archive) earMods.get(i)));
			}
			return cachedEARModules;
		}
		if (archive != null) {
			List<IArchiveResource> resources = archive.getArchiveResources();
			for (IArchiveResource resource : resources) {
				if (resource.getType() != IArchiveResource.DIRECTORY_TYPE) {
					IPath path = resource.getPath();
					if (path.segmentCount() > 0) {
						String lastSegment = path.lastSegment();
						if (lastSegment.endsWith("jar") || lastSegment.endsWith("zip") || lastSegment.endsWith("rar") || lastSegment.endsWith("war")) {
							IArchive earmodule;
							try {
								earmodule = archive.getNestedArchive(resource);
								cachedEARModules.add(new ArchiveWrapper(earmodule));
							} catch (ArchiveOpenFailureException e) {
								Logger.getLogger().logError(e);
							}
						}
					}
				}
			}
			return cachedEARModules;
		}
		fail();
		return null;
	}

	public String getName() {
		if (commonArchive != null) {
			return commonArchive.getName();
		}
		if (archive != null) {
			return archive.getPath().lastSegment();
		}
		fail();
		return null;
	}

	public boolean isModule() {
		if (isApplicationClientFile()) {
			return true;
		}
		if (isWARFile()) {
			return true;
		}
		if (isEJBJarFile()) {
			return true;
		}
		if (isRARFile()) {
			return true;
		}
		return false;
	}

	public boolean isApplicationClientFile() {
		if (commonArchive != null)
			return commonArchive.isApplicationClientFile();
		if (archive != null)
			return (JavaEEArchiveUtilities.INSTANCE.getJavaEEQuickPeek(archive).getType() == J2EEConstants.APPLICATION_CLIENT_TYPE);
		fail();
		return false;
	}

	public boolean isWARFile() {
		if (commonArchive != null)
			return commonArchive.isWARFile();
		if (archive != null)
			return (JavaEEArchiveUtilities.INSTANCE.getJavaEEQuickPeek(archive).getType() == J2EEConstants.WEB_TYPE);
		fail();
		return false;
	}

	public boolean isEJBJarFile() {
		if (commonArchive != null)
			return commonArchive.isEJBJarFile();
		if (archive != null)
			return (JavaEEArchiveUtilities.INSTANCE.getJavaEEQuickPeek(archive).getType() == J2EEConstants.EJB_TYPE);
		fail();
		return false;
	}

	public boolean isEarFile() {
		if (commonArchive != null)
			return commonArchive.isEARFile();
		if (archive != null)
			return (JavaEEArchiveUtilities.INSTANCE.getJavaEEQuickPeek(archive).getType() == J2EEConstants.APPLICATION_TYPE);
		fail();
		return false;
	}

	public boolean isRARFile() {
		if (commonArchive != null)
			return commonArchive.isRARFile();
		if (archive != null)
			return (JavaEEArchiveUtilities.INSTANCE.getJavaEEQuickPeek(archive).getType() == J2EEConstants.CONNECTOR_TYPE);
		fail();
		return false;
	}

	// This is an array so we can tell the difference between initialized and null vs not initialized
	private String[] cachedWebContextRoot = null;

	public String getWebContextRoot() {
		if (cachedWebContextRoot != null) {
			return cachedWebContextRoot[0];
		}

		if (!isWARFile()) {
			fail();
			return null;
		}
		cachedWebContextRoot = new String[1];

		if (commonArchive != null) {
			cachedWebContextRoot[0] = ((WebModule) ((EARFile) commonArchive.getContainer()).getModule(commonArchive.getURI(), null)).getContextRoot();
			return cachedWebContextRoot[0];
		}
		if (archive != null) {
			IArchive earArchive = archive.getArchive();
			if(earArchive.containsArchiveResource(new Path(J2EEConstants.APPLICATION_DD_URI))){
				JavaEEQuickPeek earJQP = JavaEEArchiveUtilities.INSTANCE.getJavaEEQuickPeek(earArchive);
				if(earJQP.getJavaEEVersion() == JavaEEQuickPeek.JEE_5_0_ID){
					try {
						Application application = (Application) earArchive.getModelObject();
						String moduleName = archive.getPath().toString();
						Module module = (Module) application.getFirstModule(moduleName);
						if(module != null){
							cachedWebContextRoot[0] = module.getWeb().getContextRoot();
						} else {
							cachedWebContextRoot[0] = getDefaultContextRoot();
						}
					} catch (ArchiveModelLoadException e) {
						Logger.getLogger().logError(e);
					}
				} else {
					try{
						org.eclipse.jst.j2ee.application.Application application = (org.eclipse.jst.j2ee.application.Application)earArchive.getModelObject();
						String moduleName = archive.getPath().toString();
						org.eclipse.jst.j2ee.application.WebModule module = (org.eclipse.jst.j2ee.application.WebModule)application.getFirstModule(moduleName);
						if(module == null){
							cachedWebContextRoot[0] = null;
						} else {
							cachedWebContextRoot[0] = module.getContextRoot();
						}
					} catch (ArchiveModelLoadException e) {
						Logger.getLogger().logError(e);
					}
				}
			} else {
				cachedWebContextRoot[0] = getDefaultContextRoot();
			}
			return cachedWebContextRoot[0];
		}
		fail();
		return null;
	}

	private String getDefaultContextRoot() {
		//J2EE spec 8.3.1.3.c (pg 149)
		String contextRoot = archive.getPath().toString();
		contextRoot = contextRoot.substring(0, contextRoot.lastIndexOf('.'));
		return contextRoot;
	}

	// This is an array so we can tell the difference between initialized and null vs not initialized
	private HashMap<ArchiveWrapper, ArchiveWrapper> cachedEJBClientArchiveWrapper = null;

	public ArchiveWrapper getEJBClientArchiveWrapper(ArchiveWrapper ejbWrapper) {
		if (cachedEJBClientArchiveWrapper == null) {
			cachedEJBClientArchiveWrapper = new HashMap<ArchiveWrapper, ArchiveWrapper>();
		}
		
		if(cachedEJBClientArchiveWrapper.containsKey(ejbWrapper)){
			return cachedEJBClientArchiveWrapper.get(ejbWrapper);
		}
		

		if (!ejbWrapper.isEJBJarFile() || !isEarFile()) {
			fail();
			return null;
		}

		ArchiveWrapper ejbClientArchiveWrapper = null;
		try{
			if (commonArchive != null) {
				try {
					EJBJar jar = ((EJBJarFile) ejbWrapper.getUnderLyingArchive()).getDeploymentDescriptor();
					if (jar != null) {
						if (jar.getEjbClientJar() != null) {
							String clientName = jar.getEjbClientJar();
							ejbClientArchiveWrapper = new ArchiveWrapper((Archive) ((EARFile) commonArchive).getFile(clientName));
						}
					}
					return ejbClientArchiveWrapper;
				} catch (FileNotFoundException e) {
					Logger.getLogger().logError(e);
				}
			}
			if (archive != null) {
				try {
					JavaEEQuickPeek jqp = JavaEEArchiveUtilities.INSTANCE.getJavaEEQuickPeek(ejbWrapper.archive);
					String clientJarName = null;
					if(jqp.getVersion() == J2EEVersionConstants.EJB_3_0_ID){
						if(ejbWrapper.archive.containsArchiveResource(new Path(J2EEConstants.EJBJAR_DD_URI))){
							org.eclipse.jst.javaee.ejb.EJBJar edd = (org.eclipse.jst.javaee.ejb.EJBJar) ejbWrapper.archive.getModelObject();
							clientJarName = edd.getEjbClientJar();
						}
					} else {
						EJBJar jar = (EJBJar)ejbWrapper.archive.getModelObject();
						if (jar != null) {
							clientJarName = jar.getEjbClientJar();
						}
					}
					
					if (null != clientJarName) {
						IPath clientJarPath = new Path(clientJarName);
						if(archive.containsArchiveResource(clientJarPath)){
							IArchiveResource clientJar = archive.getArchiveResource(clientJarPath);
							if(null != clientJar){
								if (clientJar.getType() == IArchiveResource.ARCHIVE_TYPE) {
									ejbClientArchiveWrapper = new ArchiveWrapper((IArchive) clientJar);
								} else {
									try {
										ejbClientArchiveWrapper = new ArchiveWrapper(archive.getNestedArchive(clientJar));
									} catch (ArchiveOpenFailureException e) {
										Logger.getLogger().logError(e);
									}
								}
							}
						} else {
							Logger.getLogger().logWarning(EARArchiveOpsResourceHandler.bind(EARArchiveOpsResourceHandler.MISSING_CLIENT_JAR, new Object[] {clientJarName, ejbWrapper.getName(), archive.getPath()}));
						}
					}
					return ejbClientArchiveWrapper;
				} catch (FileNotFoundException e) {
					Logger.getLogger().logError(e);
				} catch (ArchiveModelLoadException e) {
					Logger.getLogger().logError(e);
				}
			}
		} finally {
			cachedEJBClientArchiveWrapper.put(ejbWrapper, ejbClientArchiveWrapper);
		}
		fail();
		return null;
	}

	private List<ArchiveWrapper> cachedEARUtilitiesAndWebLibs = null;

	public List<ArchiveWrapper> getEARUtilitiesAndWebLibs() {
		if (null != cachedEARUtilitiesAndWebLibs) {
			return cachedEARUtilitiesAndWebLibs;
		}

		if (!isEarFile()) {
			fail();
			return null;
		}

		cachedEARUtilitiesAndWebLibs = new ArrayList<ArchiveWrapper>();
		if (commonArchive != null) {
			List files = commonArchive.getFiles();
			for (int i = 0; i < files.size(); i++) {
				FileImpl file = (FileImpl) files.get(i);
				if (file.isArchive() && !file.isModuleFile() && file.getURI().endsWith(".jar")) { //$NON-NLS-1$
					cachedEARUtilitiesAndWebLibs.add(new ArchiveWrapper((Archive) file));
				}
				if (file.isWARFile()) {
					ArchiveWrapper wrapper = new ArchiveWrapper((Archive) file);
					cachedEARUtilitiesAndWebLibs.addAll(wrapper.getWebLibs());
				}
			}
			return cachedEARUtilitiesAndWebLibs;
		}
		if (archive != null) {
			List files = archive.getArchiveResources();
			for (int i = 0; i < files.size(); i++) {
				IArchiveResource file = (IArchiveResource) files.get(i);
				String lastSegment = file.getPath().lastSegment();
				if (lastSegment.endsWith(".jar") || lastSegment.endsWith(".rar") || lastSegment.endsWith(".war") || lastSegment.endsWith("zip")) {
					IArchive nestedArchive;
					try {
						nestedArchive = archive.getNestedArchive(file);
						ArchiveWrapper nestedWrapper = new ArchiveWrapper(nestedArchive);
						if (nestedWrapper.isWARFile()) {
							cachedEARUtilitiesAndWebLibs.addAll(nestedWrapper.getWebLibs());
						} else if (!nestedWrapper.isModule()) {
							cachedEARUtilitiesAndWebLibs.add(nestedWrapper);
						}
					} catch (ArchiveOpenFailureException e) {
						Logger.getLogger().logError(e);
					}
				}
			}
			return cachedEARUtilitiesAndWebLibs;

		}
		fail();
		return null;
	}
	
}