/*******************************************************************************
 * 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;

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(archiveRelativePath.toString() +" in "+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;
	}

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

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

}