/*******************************************************************************
 * 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);
			}
		}
		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() {
		StringBuffer buffer = new StringBuffer(super.toString());
		buffer.append(" Loaded by: "); //$NON-NLS-1$
		buffer.append(loadAdapter);
		return buffer.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;
	}

}