/*******************************************************************************
 * Copyright (c) 2001, 2004 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.wst.internet.cache.internal;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Random;
import java.util.Set;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Platform;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 * The cache holds references to remote resources. The cache can store resources,
 * retrieve resources, and delete resources.
 *
 */
public class Cache 
{
  /**
   * String instances.
   */
  private static final String URI = "uri";
  private static final String LOCATION ="location";
  private static final String ENTRY = "entry";
  private static final String CACHE = "cache";
  private static final String LAST_MODIFIED = "lastModified";
  private static final String EXPIRATION_TIME = "expirationTime";
  private static final String FILE_PROTOCOL = "file:///";
  private static final String CACHE_FILE = "cache.xml";
  private static final String CACHE_EXTENSION = ".cache";
  private static final String TEMP = "temp";
  private static final String CACHE_PREFIX = "wtpcache";
  private static final String CACHE_SUFFIX = null;
  /**
   * The default timeout for a cache entry is 1 day.
   */
  private static final long TIMEOUT = 86400000;
	
  /**
   * The one and only instance of the cache.
   */
  private static Cache cacheInstance = null;
  
  /**
   * The cache is stored in a hashtable.
   */
  private Hashtable cache;
  
  /**
   * A set of uncached resources. The cache was not able to cache resources
   * in this list. This list allows quickly skipping over these resources in
   * future requests. 
   */
  private Set uncached;
  
  /**
   * The location of the cache
   */
  private File cacheLocation = null;
  
  /**
   * Private constructor.
   */
  protected Cache(IPath cacheLocation)
  {
	  this.cacheLocation = cacheLocation.toFile();//Platform.getPluginStateLocation(CachePlugin.getDefault()).toFile();
    cache = new Hashtable();
    uncached = new HashSet();
  }
  
  /**
   * Get the one and only instance of the cache.
   * 
   * @return The one and only instance of the cache.
   */
  public static Cache getInstance()
  {
//	  if(cacheInstance == null)
//	  {
//		  cacheInstance = new Cache(cacheLocation);
//		  cacheInstance.open(cacheLocation);
//	  }
	  return cacheInstance;
  }
  
  /**
   * Return the local resource for the specified uri. If there is no resource
   * the cache will attempt to download and cache the resource before returning.
   * If a remote resource cannot be cached this method will return null.
   * 
   * @param uri The URI for which a resource is requested.
   * @return The local resource for the specified URI or null if a remote resource cannot be cached.
   */
  public String getResource(String uri)
  {
	  if(uri == null) return null;
	  CacheEntry result = (CacheEntry)cache.get(uri);
	  
	  // If no result is in the cache and the URI is of an allowed type
	  // retrieve it and store it in the cache.
	  if(result == null)
	  {
      
      if(!uncached.contains(result))
		  {
        result = cacheResource(uri); 
      }
	  }
	  // Retreive a fresh copy of the result if it has timed out.
	  else if(result.hasExpired())
	  {
		result = refreshCacheEntry(result);
	  }
	  if(result == null || result.getLocalFile() == null)
	  {
		return null;
	  }
	  return FILE_PROTOCOL + cacheLocation.toString() + "/" + result.getLocalFile();
  }
  
  /**
   * Get the list of uncached resources.
   * 
   * @return The list of uncached resources.
   */
  protected String[] getUncachedURIs()
  {
    return (String[])uncached.toArray(new String[uncached.size()]);
  }
  
  /**
   * Clear the list of uncached resources.
   */
  protected void clearUncachedURIs()
  {
    uncached.clear();
  }
  
  /**
   * Add an uncached resource to the list.
   */
  protected void addUncachedURI(String uri)
  {
    uncached.add(uri);
  }
  
  /**
   * Cache the specified resource. This method creates a local version of the
   * remote resource and adds the resource reference to the cache. If the resource
   * cannot be accessed it is not added and null is returned.
   * 
   * @param uri The remote URI to cache.
   * @return A new CacheEntry representing the cached resource or null if the remote
   *         resource could not be retrieved.
   */
  protected CacheEntry cacheResource(String uri)
  {
	  CacheEntry cacheEntry = null;
	  URLConnection conn = null;
	  InputStream is = null;
	  OutputStream os = null;
	  try
	  {
		  URL url = new URL(uri);
		  conn = url.openConnection();
		  conn.connect();
		  // Determine if this resource can be cached.
		  if(conn.getUseCaches())
		  {
		    is = conn.getInputStream();//url.openStream();
		  
		    Random rand = new Random();
			String fileName = rand.nextInt() + CACHE_EXTENSION;
		    File file = new File(cacheLocation, fileName);
		    // If the file already exists we need to change the file name.
		    while(!file.createNewFile())
		    {
			  fileName = rand.nextInt() + CACHE_EXTENSION;
			  file = new File(cacheLocation,fileName);
		    }
		    os = new FileOutputStream(file);
		    byte[] bytes = new byte[1024];
		    int bytelength;
		    while((bytelength = is.read(bytes)) != -1)
		    {
			  os.write(bytes, 0, bytelength);
		    }
			long lastModified = conn.getLastModified();
		    long expiration = conn.getExpiration();
			if(expiration == 0)
			{
			  expiration = System.currentTimeMillis() + TIMEOUT;
			}
		    cacheEntry = new CacheEntry(uri, fileName, lastModified, expiration);
		    cache.put(uri,cacheEntry);
		  }

	  }
	  catch(Throwable t)
	  {
		  // Put the entry in the uncached list so the resolution work will not be performed again.
      // TODO: Add in a timeout for the non-located uris.
      uncached.add(uri);
	  }
	  finally
	  {
		  if(is != null)
		  {
			  try
			  {
			    is.close();
			  }
			  catch(IOException e)
			  {
			    // Do nothing if the stream cannot be closed.
			  }
		  }
		  if(os != null)
		  {
			  try
			  {
			    os.close();
			  }
			  catch(IOException e)
			  {
				// Do nothing if the stream cannot be closed. 
			  }
		  }
	  }
	  return cacheEntry;
  }
  
  /**
   * Refresh the cache entry if necessary. The cache entry will be refreshed
   * if the remote resource is accessible and the last modified time of the
   * remote resource is greater than the last modified time of the cached
   * resource.
   * 
   * @param cacheEntry The cache entry to refresh.
   * @return The refreshed cache entry.
   */
  protected CacheEntry refreshCacheEntry(CacheEntry cacheEntry)
  {
	  URLConnection conn = null;
	  InputStream is = null;
	  OutputStream os = null;
	  try
	  {
		  URL url = new URL(cacheEntry.getURI());
		  conn = url.openConnection();
		  conn.connect();
		  
		  long lastModified = conn.getLastModified();
	      if(lastModified > cacheEntry.getLastModified())
		  {
			long expiration = conn.getExpiration();
		    if(expiration == 0)
			{
			  expiration = System.currentTimeMillis() + TIMEOUT;
			}
			
		    is = conn.getInputStream();
			
			String localFile = cacheEntry.getLocalFile();
  
		    File tempFile = File.createTempFile(CACHE_PREFIX, CACHE_SUFFIX);
			tempFile.deleteOnExit();

		    os = new FileOutputStream(tempFile);
		    byte[] bytes = new byte[1024];
		    int bytelength;
		    while((bytelength = is.read(bytes)) != -1)
		    {
			  os.write(bytes, 0, bytelength);
		    }
			is.close();
			os.close();
			deleteFile(cacheEntry.getURI());
			File f = new File(cacheLocation, localFile);
			tempFile.renameTo(f);
			cacheEntry.setExpiration(expiration);
			cacheEntry.setLastModified(lastModified);
		  }
		  // The cache entry hasn't changed. Just update the expiration time.
	      else
		  {
			long expiration = conn.getExpiration();
			if(expiration == 0)
			{
			  expiration = System.currentTimeMillis() + TIMEOUT;
			}
			cacheEntry.setExpiration(expiration);
		  }

	  }
	  catch(Exception e)
	  {
      // Do nothing.
	  }
	  finally
	  {
		  if(is != null)
		  {
			  try
			  {
			    is.close();
			  }
			  catch(IOException e)
			  {
			    // Do nothing if the stream cannot be closed.
			  }
		  }
		  if(os != null)
		  {
			  try
			  {
			    os.close();
			  }
			  catch(IOException e)
			  {
				// Do nothing if the stream cannot be closed. 
			  }
		  }
	  }
	  return cacheEntry;
  }
  
  /**
   * Get an array of the cached URIs.
   * 
   * @return An array of the cached URIs.
   */
  public String[] getCachedURIs()
  {
	Set keyset = cache.keySet();
	return (String[])keyset.toArray(new String[keyset.size()]);
  }
  
  /**
   * Close the cache. Closing the cache involves serializing the data to an XML file
   * in the plugin state location.
   */
  protected void close()
  {
	  DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
      try {
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document cachedoc = builder.newDocument();
		Element rootelem = cachedoc.createElement(CACHE);
		cachedoc.appendChild(rootelem);
		
	  Enumeration uris = cache.keys();
	  while(uris.hasMoreElements())
	  {
		  String key = (String)uris.nextElement();
		  CacheEntry cacheEntry = (CacheEntry)cache.get(key);
		  if(cacheEntry != null)
		  {
			  Element entry = cachedoc.createElement(ENTRY);
			  entry.setAttribute(URI, key);
			  entry.setAttribute(LOCATION, cacheEntry.getLocalFile());
			  entry.setAttribute(EXPIRATION_TIME, String.valueOf(cacheEntry.getExpirationTime()));
			  entry.setAttribute(LAST_MODIFIED, String.valueOf(cacheEntry.getLastModified()));
			  rootelem.appendChild(entry);
		  }
	  }
	  
	  // Write the cache entry.
	  TransformerFactory tFactory  = TransformerFactory.newInstance();
      Transformer transformer = tFactory.newTransformer();
      Source input = new DOMSource(cachedoc);
	  IPath stateLocation = Platform.getPluginStateLocation(CachePlugin.getDefault());
      Result output = new StreamResult(stateLocation.toString() + "/" + CACHE_FILE);
      transformer.transform(input, output);

      }catch(Exception e)
	  {
		  System.out.println("Unable to store internet cache.");
	  }
	  cacheInstance = null;
  }
  
  /**
   * Open the cache. Opening the cache involves parsing the cache XML file in
   * the plugin state location if it can be read.
   */
  protected static void open(IPath cacheLocation)
  {
    cacheInstance = new Cache(cacheLocation);
	  DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
      try {
		  
		IPath stateLocation = cacheLocation;
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document cachedoc = builder.parse(stateLocation.toString() + "/" + CACHE_FILE);
		Element rootelem = cachedoc.getDocumentElement();
		NodeList entries = rootelem.getChildNodes();
		int numEntries = entries.getLength();
		for(int i = 0; i < numEntries; i++)
		{
			Node entry = entries.item(i);
			if(entry instanceof Element)
			{
				Element e = (Element)entry;
				if(e.getNodeName().equals(ENTRY))
				{
					String uri = e.getAttribute(URI);
					String location = e.getAttribute(LOCATION);
					String lm = e.getAttribute(LAST_MODIFIED);
					String et = e.getAttribute(EXPIRATION_TIME);
					long lastModified = -1;
					long expirationTime = -1;
					try
					{
						lastModified = Long.parseLong(lm);
					}
					catch(NumberFormatException nfe)
					{
					}
					try
					{
						expirationTime = Long.parseLong(et);
					}
					catch(NumberFormatException nfe)
					{
					}
					if(uri != null && location != null)
					{
					  cacheInstance.cache.put(uri, new CacheEntry(uri, location, lastModified, expirationTime));
					}
				}
			}
		}
      }
	  catch(FileNotFoundException e)
	  {
		// If the file doesn't exist in the correct location there is nothing to load. Do nothing.
	  }
	  catch(Exception e)
	  {
		  System.out.println("Unable to load cache.");
	  }
  }
  
  /**
   * Clear all of the entries from the cache. This method also deletes the cache files.
   */
  public void clear()
  {
	Enumeration keys = cache.keys();
	while(keys.hasMoreElements())
	{
	  String key = (String)keys.nextElement();
	  
	  deleteFile(key);
	}
	cache.clear();
  }
  
  /**
   * Delete the cache entry specified by the given URI.
   * @param uri The URI entry to remove from the catalog.
   */
  public void deleteEntry(String uri)
  {
	  if(uri == null) return;
	  
	  deleteFile(uri);
	  cache.remove(uri);
  }
  
  /**
   * Delete the file specified by the URI.
   * 
   * @param uri The URI of the file to delete.
   */
  protected void deleteFile(String uri)
  {
	  CacheEntry cacheEntry = (CacheEntry)cache.get(uri);
	  if(cacheEntry != null)
	  {
		String location = cacheLocation.toString() + "/" + cacheEntry.getLocalFile();
	    File file = new File(location);
	    if(!file.delete())
	    {
	      System.out.println("Unable to delete file " + location + " from cache.");
	    } 
	  }
  }
}