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

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

import org.eclipse.core.runtime.IPath;
import org.eclipse.jst.jee.archive.AbstractArchiveLoadAdapter;
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.IArchiveResource;
import org.eclipse.jst.j2ee.commonarchivecore.internal.CommonArchiveResourceHandler;
import org.eclipse.osgi.util.NLS;

public class ArchiveImpl extends ArchiveResourceImpl implements IArchive {

	private ArchiveOptions archiveOptions;

	private IArchiveLoadAdapter loadAdapter;

	private class ArchiveFileIndex {
		private Map<IPath, IArchiveResource> index = new HashMap<IPath, IArchiveResource>();

		private List<IArchive> nestedArchives = null;

		private List<IArchiveResource> fullIndex = null;

		private boolean fullyIndexed = false;

		public ArchiveFileIndex() {
		}

		public synchronized List<IArchive> getNestedArchives() {
			if (nestedArchives == null) {
				nestedArchives = new ArrayList<IArchive>();
			}
			return nestedArchives;
		}

		public synchronized boolean containsFile(IPath archiveRelativePath) {
			AbstractArchiveLoadAdapter.verifyRelative(archiveRelativePath);
			return index.containsKey(archiveRelativePath);
		}

		public synchronized IArchiveResource getFile(IPath archiveRelativePath) {
			AbstractArchiveLoadAdapter.verifyRelative(archiveRelativePath);
			IArchiveResource aFile = index.get(archiveRelativePath);
			return aFile;
		}

		public synchronized void noteEmptyFile(IPath archiveRelativePath) {
			verifyNotFullyIndexed();
			AbstractArchiveLoadAdapter.verifyRelative(archiveRelativePath);
			index.put(archiveRelativePath, null);
		}

		public synchronized void addFile(IArchiveResource aFile) {
			verifyNotFullyIndexed();
			AbstractArchiveLoadAdapter.verifyRelative(aFile.getPath());
			index.put(aFile.getPath(), aFile);
		}

		public synchronized boolean isFullyIndexed() {
			return fullyIndexed;
		}

		public void fullyIndex(List<IArchiveResource> files) {
			synchronized (this) {
				if (fullyIndexed) {
					verifyNotFullyIndexed();
				}
				fullyIndexed = true;
			}

			for (IArchiveResource aFile : files) {
				AbstractArchiveLoadAdapter.verifyRelative(aFile.getPath());
				synchronized (this) {
					if (!index.containsKey(aFile.getPath())) {
						index.put(aFile.getPath(), aFile);
					}
				}
			}
		}

		public synchronized List<IArchiveResource> getFullIndex() {
			if (!isFullyIndexed()) {
				throw new RuntimeException("File list has not been fully indexed"); //$NON-NLS-1$
			}
			if (fullIndex == null) {
				List<IArchiveResource> list = new ArrayList<IArchiveResource>();
				list.addAll(index.values());
				fullIndex = Collections.unmodifiableList(list);
			}
			return fullIndex;
		}

		private void verifyNotFullyIndexed() {
			if (isFullyIndexed()) {
				throw new RuntimeException("Attempting to modify a fully indexed file list"); //$NON-NLS-1$
			}
		}
	}

	private ArchiveFileIndex archiveFileIndex = new ArchiveFileIndex();

	private FailedToCloseException openendBy = null;

	public ArchiveImpl(ArchiveOptions archiveOptions) {
		setType(IArchiveResource.ARCHIVE_TYPE);
		setArchiveOptions(archiveOptions);
		loadAdapter = (IArchiveLoadAdapter) getArchiveOptions().getOption(ArchiveOptions.LOAD_ADAPTER);
		loadAdapter.setArchive(this);
		openendBy = new FailedToCloseException();
	}

	public boolean isOpen() {
		return openendBy != null;
	}

	public void close() {
		if(isOpen()){
			openendBy = null;
			for (IArchive nestedArchive : getNestedArchives()) {
				IArchiveFactory.INSTANCE.closeArchive(nestedArchive);
			}
			loadAdapter.close();
			dispose();
		}
	}

	@Override
	protected void dispose() {
		super.dispose();
		archiveFileIndex = null;
		loadAdapter = null;
		archiveFactory = null;
		archiveOptions = null;
	}

	public IArchiveResource getArchiveResource(IPath archiveRelativePath) throws FileNotFoundException {
		AbstractArchiveLoadAdapter.verifyRelative(archiveRelativePath);
		IArchiveResource aFile = null;
		if (archiveFileIndex.containsFile(archiveRelativePath)) {
			aFile = archiveFileIndex.getFile(archiveRelativePath);
		} else if (!archiveFileIndex.isFullyIndexed()) {
			aFile = loadAdapter.getArchiveResource(archiveRelativePath);
			if (aFile == null) {
				archiveFileIndex.noteEmptyFile(archiveRelativePath);
			} else {
				archiveFileIndex.addFile(aFile);
			}
		}
		if(aFile == null){
			throw new FileNotFoundException(NLS.bind(CommonArchiveResourceHandler.ArchiveImpl_0_in_1_, new Object[] { archiveRelativePath.toString(), toString() }));
		}
		return aFile;
	}

	public List<IArchiveResource> getArchiveResources() {
		synchronized (this) {
			if (!archiveFileIndex.isFullyIndexed()) {
				archiveFileIndex.fullyIndex(loadAdapter.getArchiveResources());
			}
		}
		return archiveFileIndex.getFullIndex();
	}

	public void setLoadAdapter(IArchiveLoadAdapter loadAdapter) {
		this.loadAdapter = loadAdapter;
	}
	
	public IArchiveLoadAdapter getLoadAdapter() {
		return loadAdapter;
	}

	protected void setArchiveOptions(ArchiveOptions archiveOptions) {
		this.archiveOptions = archiveOptions;
	}

	public ArchiveOptions getArchiveOptions() {
		return archiveOptions;
	}

	@Override
	public String toString() {
		return loadAdapter.toString();
	}

	@Override
	protected void finalize() throws Throwable {
		super.finalize();
		if (isOpen()) {
			System.err.println("Archive opener did not close archive: " + this); //$NON-NLS-1$
			System.err.println("Archive was opened here:"); //$NON-NLS-1$
			openendBy.printStackTrace(System.err);
			close();
		}
	}

	public boolean containsModelObject() {
		return containsModelObject(IArchive.EMPTY_MODEL_PATH);
	}

	public boolean containsModelObject(IPath modelObjectPath) {
		AbstractArchiveLoadAdapter.verifyRelative(modelObjectPath);
		return getLoadAdapter().containsModelObject(modelObjectPath);
	}

	public Object getModelObject() throws ArchiveModelLoadException {
		return getModelObject(IArchive.EMPTY_MODEL_PATH);
	}

	public Object getModelObject(IPath modelObjectPath) throws ArchiveModelLoadException {
		AbstractArchiveLoadAdapter.verifyRelative(modelObjectPath);
		return getLoadAdapter().getModelObject(modelObjectPath);
	}

	public boolean containsArchiveResource(IPath archiveRelativePath) {
		AbstractArchiveLoadAdapter.verifyRelative(archiveRelativePath);
		if (archiveFileIndex.containsFile(archiveRelativePath)) {
			return true;
		} else if (!archiveFileIndex.isFullyIndexed()) {
			return loadAdapter.containsArchiveResource(archiveRelativePath);
		}
		return false;
	}

	public IArchive getNestedArchive(IArchiveResource archiveResource) throws ArchiveOpenFailureException {
		try {
			if (archiveResource.getArchive() != this) {
				throw new ArchiveOpenFailureException("Attempted to open nested IArchive " + archiveResource.getPath() + " using an IArchiveResource not contained in this IArchive."); //$NON-NLS-1$//$NON-NLS-2$
			}
			getArchiveResources(); // need to force the full index to be built now.
			IArchiveResource cachedArchiveResource = getArchiveResource(archiveResource.getPath());

			if (cachedArchiveResource.getType() == IArchiveResource.ARCHIVE_TYPE) {
				IArchive nestedArchive = (IArchive) cachedArchiveResource;
				if (!archiveFileIndex.getNestedArchives().contains(nestedArchive)) {
					archiveFileIndex.getNestedArchives().add(nestedArchive);
				}
				return nestedArchive;
			} else if (cachedArchiveResource.getType() == IArchiveResource.DIRECTORY_TYPE) {
				throw new ArchiveOpenFailureException("Attempted to open nested IArchive " + cachedArchiveResource.getPath() + " using a directory."); //$NON-NLS-1$//$NON-NLS-2$
			}
			IArchiveLoadAdapter nestedLoadAdapter = null;

			try {
				java.io.File tempFile = null;
				try {
					tempFile = ArchiveUtil.createTempFile(cachedArchiveResource.getPath().toString());
				} catch (IOException e) {
					ArchiveUtil.warn("Warning: Unable to create temp file for " + cachedArchiveResource.getPath() + ".  This will impact performance."); //$NON-NLS-1$//$NON-NLS-2$
				}
				if (tempFile != null) {
					InputStream in = cachedArchiveResource.getInputStream();
					OutputStream out = new FileOutputStream(tempFile);
					ArchiveUtil.copy(in, out);
					nestedLoadAdapter = new TempZipFileArchiveLoadAdapterImpl(tempFile);
				}
			} catch (IOException e) {
				throw new ArchiveOpenFailureException(e);
			}

			if (nestedLoadAdapter == null) {
				// TODO implement a ZipStream reader if necessary
			}

			ArchiveOptions nestedArchiveOptions = cloneUnknownOptions(archiveOptions);
			nestedArchiveOptions.setOption(ArchiveOptions.PARENT_ARCHIVE, this);
			nestedArchiveOptions.setOption(ArchiveOptions.LOAD_ADAPTER, nestedLoadAdapter);
			nestedArchiveOptions.setOption(ArchiveOptions.ARCHIVE_PATH, cachedArchiveResource.getPath());
			IArchive nestedArchive = archiveFactory.openArchive(nestedArchiveOptions);
			nestedArchive.setPath(cachedArchiveResource.getPath());
			nestedArchive.setArchive(this);
			return nestedArchive;

		} catch (FileNotFoundException e) {
			throw new ArchiveOpenFailureException(e);
		}
	}

	protected ArchiveOptions cloneUnknownOptions(ArchiveOptions archiveOptions){
		ArchiveOptions newOptions = new ArchiveOptions();
		Iterator iterator = archiveOptions.keySet().iterator();
		while(iterator.hasNext()){
			Object key = iterator.next();
			if(key == ArchiveOptions.ARCHIVE_PATH || key == ArchiveOptions.LOAD_ADAPTER || key == ArchiveOptions.SAVE_ADAPTER){
				continue;
			} else {
				newOptions.setOption(key, archiveOptions.getOption(key));
			}
		}
		return newOptions;
	}
	
	
	public List<IArchive> getNestedArchives() {
		return Collections.unmodifiableList(archiveFileIndex.getNestedArchives());
	}

	/**
	 * Internal
	 * 
	 * @param archiveResource
	 */
	void addArchiveResourceInternal(IArchiveResource archiveResource) {
		archiveFileIndex.index.put(archiveResource.getPath(), archiveResource);
		if(archiveResource.getType() == ARCHIVE_TYPE){
			archiveFileIndex.getNestedArchives().add((IArchive)archiveResource);
		}
		archiveFileIndex.fullIndex = null;
	}
	
	protected IArchiveFactory archiveFactory;
	/**
	 * Internal; clients should not call.
	 * @param archiveFactory
	 */
	public void setArchiveFactory(IArchiveFactory archiveFactory){
		this.archiveFactory = archiveFactory;
	}

}