/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the  "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*
 * $Id$
 */

package org.apache.xalan.xsltc.dom;

import java.io.File;
import java.io.PrintWriter;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLDecoder;
import java.util.Date;
import java.util.Hashtable;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.TransformerException;
import javax.xml.transform.sax.SAXSource;

import org.apache.xalan.xsltc.DOM;
import org.apache.xalan.xsltc.DOMCache;
import org.apache.xalan.xsltc.DOMEnhancedForDTM;
import org.apache.xalan.xsltc.Translet;
import org.apache.xalan.xsltc.runtime.AbstractTranslet;
import org.apache.xalan.xsltc.runtime.BasisLibrary;
import org.apache.xalan.xsltc.runtime.Constants;
import org.apache.xml.utils.SystemIDResolver;

import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;

/**
 * @author Morten Jorgensen
 */
public final class DocumentCache implements DOMCache {

    private int       _size;
    private Hashtable _references;
    private String[]  _URIs;
    private int       _count;
    private int       _current;
    private SAXParser _parser;
    private XMLReader _reader;
    private XSLTCDTMManager _dtmManager;

    private static final int REFRESH_INTERVAL = 1000;

    /*
     * Inner class containing a DOMImpl object and DTD handler
     */
    public final class CachedDocument {
	
	// Statistics data
	private long _firstReferenced;
	private long _lastReferenced;
	private long _accessCount;
	private long _lastModified;
	private long _lastChecked;
	private long _buildTime;

	// DOM and DTD handler references
	private DOMEnhancedForDTM _dom = null;
	
	/**
	 * Constructor - load document and initialise statistics
	 */
	public CachedDocument(String uri) {
	    // Initialise statistics variables
	    final long stamp = System.currentTimeMillis();
	    _firstReferenced = stamp;
	    _lastReferenced  = stamp;
	    _accessCount     = 0;
	    loadDocument(uri);

	    _buildTime = System.currentTimeMillis() - stamp;
	}

	/**
	 * Loads the document and updates build-time (latency) statistics
	 */
	public void loadDocument(String uri) {

	    try {
		final long stamp = System.currentTimeMillis();
                _dom = (DOMEnhancedForDTM)_dtmManager.getDTM(
                                 new SAXSource(_reader, new InputSource(uri)),
                                 false, null, true, false);
		_dom.setDocumentURI(uri);

		// The build time can be used for statistics for a better
		// priority algorithm (currently round robin).
		final long thisTime = System.currentTimeMillis() - stamp;
		if (_buildTime > 0)
		    _buildTime = (_buildTime + thisTime) >>> 1;
		else
		    _buildTime = thisTime;
	    }
	    catch (Exception e) {
		_dom = null;
	    }
	}

	public DOM getDocument()       { return(_dom); }

	public long getFirstReferenced()   { return(_firstReferenced); }

	public long getLastReferenced()    { return(_lastReferenced); }

	public long getAccessCount()       { return(_accessCount); }

	public void incAccessCount()       { _accessCount++; }

	public long getLastModified()      { return(_lastModified); }

	public void setLastModified(long t){ _lastModified = t; }

	public long getLatency()           { return(_buildTime); }

	public long getLastChecked()       { return(_lastChecked); }
	
	public void setLastChecked(long t) { _lastChecked = t; }

	public long getEstimatedSize() {
	    if (_dom != null)
		return(_dom.getSize() << 5); // ???
	    else
		return(0);
	}

    }

    /**
     * DocumentCache constructor
     */
    public DocumentCache(int size) throws SAXException {
        this(size, null);
        try {
            _dtmManager = (XSLTCDTMManager)XSLTCDTMManager.getDTMManagerClass()
                                                          .newInstance();
        } catch (Exception e) {
            throw new SAXException(e);
        }
    }

    /**
     * DocumentCache constructor
     */
    public DocumentCache(int size, XSLTCDTMManager dtmManager) throws SAXException {
	_dtmManager = dtmManager;
	_count = 0;
	_current = 0;
	_size  = size;
	_references = new Hashtable(_size+2);
	_URIs = new String[_size];

	try {
	    // Create a SAX parser and get the XMLReader object it uses
	    final SAXParserFactory factory = SAXParserFactory.newInstance();
	    try {
		factory.setFeature(Constants.NAMESPACE_FEATURE,true);
	    }
	    catch (Exception e) {
		factory.setNamespaceAware(true);
	    }
	    _parser = factory.newSAXParser();
	    _reader = _parser.getXMLReader();
	}
	catch (ParserConfigurationException e) {
	    BasisLibrary.runTimeError(BasisLibrary.NAMESPACES_SUPPORT_ERR);
	}
    }

    /**
     * Returns the time-stamp for a document's last update
     */
    private final long getLastModified(String uri) {
	try {
	    URL url = new URL(uri);
	    URLConnection connection = url.openConnection();
	    long timestamp = connection.getLastModified();
	    // Check for a "file:" URI (courtesy of Brian Ewins)
	    if (timestamp == 0){ // get 0 for local URI
	        if ("file".equals(url.getProtocol())){
	            File localfile = new File(URLDecoder.decode(url.getFile()));
	            timestamp = localfile.lastModified();
	        }
	    }
	    return(timestamp);
	}
	// Brutal handling of all exceptions
	catch (Exception e) {
	    return(System.currentTimeMillis());
	}
    }

    /**
     *
     */
    private CachedDocument lookupDocument(String uri) {
	return((CachedDocument)_references.get(uri));
    }

    /**
     *
     */
    private synchronized void insertDocument(String uri, CachedDocument doc) {
	if (_count < _size) {
	    // Insert out URI in circular buffer
	    _URIs[_count++] = uri;
	    _current = 0;
	}
	else {
	    // Remove oldest URI from reference Hashtable
	    _references.remove(_URIs[_current]);
	    // Insert our URI in circular buffer
	    _URIs[_current] = uri;
	    if (++_current >= _size) _current = 0;
	}
	_references.put(uri, doc);
    }

    /**
     *
     */
    private synchronized void replaceDocument(String uri, CachedDocument doc) {
	CachedDocument old = (CachedDocument)_references.get(uri);
	if (doc == null)
	    insertDocument(uri, doc);
	else
	    _references.put(uri, doc);
    }

    /**
     * Returns a document either by finding it in the cache or
     * downloading it and putting it in the cache.
     */
    public DOM retrieveDocument(String baseURI, String href, Translet trs) {
	CachedDocument doc;

    String uri = href;
    if (baseURI != null && baseURI.length() != 0) {
        try {
            uri = SystemIDResolver.getAbsoluteURI(uri, baseURI);
        } catch (TransformerException te) {
            // ignore    
        }
    }
    
	// Try to get the document from the cache first
	if ((doc = lookupDocument(uri)) == null) {
	    doc = new CachedDocument(uri);
	    if (doc == null) return null; // better error handling needed!!!
	    doc.setLastModified(getLastModified(uri));
	    insertDocument(uri, doc);
	}
	// If the document is in the cache we must check if it is still valid
	else {
	    long now = System.currentTimeMillis();
	    long chk = doc.getLastChecked();
	    doc.setLastChecked(now);
	    // Has the modification time for this file been checked lately?
	    if (now > (chk + REFRESH_INTERVAL)) {
		doc.setLastChecked(now);
		long last = getLastModified(uri);
		// Reload document if it has been modified since last download
		if (last > doc.getLastModified()) {
		    doc = new CachedDocument(uri);
		    if (doc == null) return null;
		    doc.setLastModified(getLastModified(uri));
		    replaceDocument(uri, doc);
		}
	    }
	    
	}

	// Get the references to the actual DOM and DTD handler
	final DOM dom = doc.getDocument();

	// The dom reference may be null if the URL pointed to a
	// non-existing document
	if (dom == null) return null;

	doc.incAccessCount(); // For statistics

	final AbstractTranslet translet = (AbstractTranslet)trs;

	// Give the translet an early opportunity to extract any
        // information from the DOM object that it would like.
	translet.prepassDocument(dom);

	return(doc.getDocument());
    }

    /**
     * Outputs the cache statistics
     */
    public void getStatistics(PrintWriter out) {
	out.println("<h2>DOM cache statistics</h2><center><table border=\"2\">"+
		    "<tr><td><b>Document URI</b></td>"+
		    "<td><center><b>Build time</b></center></td>"+
		    "<td><center><b>Access count</b></center></td>"+
		    "<td><center><b>Last accessed</b></center></td>"+
		    "<td><center><b>Last modified</b></center></td></tr>");

	for (int i=0; i<_count; i++) {
	    CachedDocument doc = (CachedDocument)_references.get(_URIs[i]);
	    out.print("<tr><td><a href=\""+_URIs[i]+"\">"+
		      "<font size=-1>"+_URIs[i]+"</font></a></td>");
	    out.print("<td><center>"+doc.getLatency()+"ms</center></td>");
	    out.print("<td><center>"+doc.getAccessCount()+"</center></td>");
	    out.print("<td><center>"+(new Date(doc.getLastReferenced()))+
		      "</center></td>");
	    out.print("<td><center>"+(new Date(doc.getLastModified()))+
		      "</center></td>");
	    out.println("</tr>");
	}

	out.println("</table></center>");
    }
}
