/*******************************************************************************
 * 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.jsp.core.internal.util;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.lang.ref.Reference;
import java.lang.ref.SoftReference;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.eclipse.core.filebuffers.FileBuffers;
import org.eclipse.core.filebuffers.ITextFileBuffer;
import org.eclipse.core.filebuffers.LocationKind;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.QualifiedName;
import org.eclipse.core.runtime.content.IContentDescription;
import org.eclipse.jst.jsp.core.internal.Logger;
import org.eclipse.wst.sse.core.internal.util.Debug;

public class FileContentCache {
	private static class CacheEntry {
		String contents;
		long modificationStamp = IResource.NULL_STAMP;
		IPath path;

		CacheEntry(IPath path) {
			this.path = path;
			modificationStamp = getModificationStamp(path);
			contents = readContents(path);
		}

		private IFile getFile(IPath path) {
			if (path.segmentCount() > 1) {
				return ResourcesPlugin.getWorkspace().getRoot().getFile(path);
			}
			return null;
		}

		boolean isStale() {
			if (modificationStamp == IResource.NULL_STAMP) {
				return true;
			}
			long newStamp = getModificationStamp(path);
			return newStamp > modificationStamp;
		}

		private String detectCharset(IFile file) {
			if (file.getType() == IResource.FILE && file.isAccessible()) {
				IContentDescription d = null;
				try {
					// optimized description lookup, might not succeed
					d = file.getContentDescription();
					if (d != null)
						return d.getCharset();
				}
				catch (CoreException e) {
					// should not be possible given the accessible and file
					// type
					// check above
				}
				InputStream contents = null;
				try {
					contents = file.getContents();
					IContentDescription description = Platform.getContentTypeManager().getDescriptionFor(contents, file.getName(), new QualifiedName[]{IContentDescription.CHARSET});
					if (description != null) {
						return description.getCharset();
					}
				}
				catch (IOException e) {
					// will try to cleanup in finally
				}
				catch (CoreException e) {
					Logger.logException(e);
				}
				finally {
					if (contents != null) {
						try {
							contents.close();
						}
						catch (Exception e) {
							// not sure how to recover at this point
						}
					}
				}
			}
			return ResourcesPlugin.getEncoding();
		}

		private long getModificationStamp(IPath filePath) {
			IFile f = getFile(filePath);
			if (f != null && f.isAccessible()) {
				return f.getModificationStamp();
			}
			File file = filePath.toFile();
			if (file.exists())
				return file.lastModified();
			return IResource.NULL_STAMP;
		}

		private String readContents(IPath filePath) {
			if (DEBUG)
				System.out.println("readContents:" + filePath);
			StringBuffer s = new StringBuffer();
			InputStream is = null;
			try {
				IFile f = getFile(filePath);
				if (f != null && f.isAccessible()) {
					String charset = detectCharset(f);
					is = f.getContents();
					Reader reader = new InputStreamReader(is, charset);
					char[] readBuffer = new char[2048];
					int n = reader.read(readBuffer);
					while (n > 0) {
						s.append(readBuffer, 0, n);
						n = reader.read(readBuffer);
					}
				}
			}
			catch (Exception e) {
				if (Debug.debugStructuredDocument) {
					Logger.logException(e);
					e.printStackTrace();
				}
			}
			finally {
				try {
					if (is != null) {
						is.close();
					}
				}
				catch (Exception e) {
					// nothing to do
				}
			}
			if (is == null) {
				try {
					FileBuffers.getTextFileBufferManager().connect(filePath, LocationKind.LOCATION, new NullProgressMonitor());
					ITextFileBuffer buffer = FileBuffers.getTextFileBufferManager().getTextFileBuffer(filePath, LocationKind.LOCATION);
					if (buffer != null) {
						s.append(buffer.getDocument().get());
					}
				}
				catch (CoreException e) {
					// nothing to do
					Logger.logException(e);
				}
				finally {
					try {
						FileBuffers.getTextFileBufferManager().disconnect(filePath, LocationKind.LOCATION, new NullProgressMonitor());
					}
					catch (CoreException e) {
						Logger.logException(e);
					}
				}
			}
			return s.toString();
		}

	}

	static final boolean DEBUG = false;

	static FileContentCache instance = new FileContentCache();

	public static FileContentCache getInstance() {
		return instance;
	}

	private HashMap fContentMap;

	private FileContentCache() {
		super();
		fContentMap = new HashMap();
	}

	private void cleanup() {
		Iterator iterator = fContentMap.entrySet().iterator();
		while (iterator.hasNext()) {
			Map.Entry entry = (Map.Entry) iterator.next();
			if (entry.getValue() != null && ((Reference) entry.getValue()).get() == null) {
				iterator.remove();
			}
		}
	}

	public String getContents(IPath filePath) {
		if (DEBUG)
			System.out.println("getContents:" + filePath);
		CacheEntry entry = null;
		Object o = fContentMap.get(filePath);
		if (o instanceof Reference) {
			entry = (CacheEntry) ((Reference) o).get();
		}
		if (entry == null || entry.isStale()) {
			if (DEBUG && entry != null && entry.isStale())
				System.out.println("stale contents:" + filePath);
			entry = new CacheEntry(filePath);
			fContentMap.put(filePath, new SoftReference(entry));
		}
		cleanup();
		return entry.contents;
	}


}
