/*******************************************************************************
 * 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() {
		openendBy = null;
		for (IArchive nestedArchive : getNestedArchives()) {
			IArchiveFactory.INSTANCE.closeArchive(nestedArchive);
		}
		loadAdapter.close();
	}

	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$
			}
			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;
	}

}