/*
 * Created on 20-Apr-2005
 */
package org.bodington.server.resources;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.log4j.Logger;

/**
 * Class used to cache external Feeds. The cache is only around as long as
 * the original resource is cached by the Bodington SoftCache.
 * This is an UGLY hack.
 * @author buckett
 */
public class FeedCache
{
    private Logger log = Logger.getLogger(FeedCache.class);
    
    private String data = "";
    private long lastChecked = 0;
    private long lastFailed = 0;
    private String url = "";
    private FeedResource resource;
    private HttpClient httpClient = new HttpClient();
    
    private static long CHECK_INTERVAL = 1800000;
    // Only check failing URLs every 20 minutes.
    private static long FAIL_INTERVAL= 1200000;
    
    /**
     * Create a new FeedCache. We need a referece to the
     * resource so we can get the URL we should be visiting.
     * @param resource The resource this is a cache of.
     */
    public FeedCache(FeedResource resource)
    {
        this.resource = resource;
    }
    
    /**
     * This returns the data from the URL.
     * @return String representation of the feed.
     */
    public String getData()
    {
        return data;
    }
    
    /**
     * Attempt to update the data.
     */
    public synchronized void update()
    {
        long now = System.currentTimeMillis();
        String url = resource.getURL();
        
        if ( (! this.url.equals(url)) || now - lastChecked > CHECK_INTERVAL && now - lastFailed > FAIL_INTERVAL)
        {
            this.url = url;
            try
            {
                fastCheck(url);
                lastChecked = now;
                lastFailed = 0;
            }
            catch (Exception e)
            {
                log.warn("Failed to get: "+ url);
                lastFailed = now;
            }
        }
    }
    
    private void fastCheck(String url) throws Exception
    {

        HttpMethod method = new GetMethod(url);
        httpClient.setConnectionTimeout(1000);
        httpClient.setTimeout(2000);
        httpClient.executeMethod(method);
        switch (method.getStatusCode())
        {
            case HttpStatus.SC_OK:
                data = method.getResponseBodyAsString();
            case HttpStatus.SC_NOT_MODIFIED:
                break;
            default:
                 throw new HttpException("Request wasn't sucessfull, code: "+ method.getStatusCode());
        }
    }

}
