/*******************************************************************************
 * 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 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(uri))
	    {
          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.");
	    } 
	  }
  }
}