package org.apache.maven.doxia.macro.snippet;

/*
 * 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.
 */

import org.apache.maven.doxia.macro.AbstractMacro;
import org.apache.maven.doxia.macro.Macro;
import org.apache.maven.doxia.macro.MacroExecutionException;
import org.apache.maven.doxia.macro.MacroRequest;
import org.apache.maven.doxia.sink.Sink;
import org.apache.maven.doxia.sink.impl.SinkEventAttributeSet;
import org.codehaus.plexus.component.annotations.Component;
import org.codehaus.plexus.util.StringUtils;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

/**
 * A macro that prints out the content of a file or a URL.
 *
 * @version $Id$
 */
@Component( role = Macro.class, hint = "snippet" )
public class SnippetMacro
    extends AbstractMacro
{
    /**
     * Holds the cache.
     */
    private static Map<String, String> cache = new HashMap<String, String>();

    private static final int HOUR = 60;

    /**
     * One hour default cache.
     */
    private long timeout = HOUR * HOUR * 1000;

    /**
     * Holds the time cache.
     */
    private static Map<String, Long> timeCached = new HashMap<String, Long>();

    /**
     * Debug.
     */
    private boolean debug = false;

    /**
     * in case of Exception during snippet download error will ignored and empty content returned.
     */
    private boolean ignoreDownloadError = true;

    /**
     * {@inheritDoc}
     */
    public void execute( Sink sink, MacroRequest request )
        throws MacroExecutionException
    {
        String id = (String) request.getParameter( "id" );

        String urlParam = (String) request.getParameter( "url" );

        String fileParam = (String) request.getParameter( "file" );

        String debugParam = (String) request.getParameter( "debug" );

        if ( debugParam != null )
        {
            this.debug = Boolean.parseBoolean( debugParam );
        }

        String ignoreDownloadErrorParam = (String) request.getParameter( "ignoreDownloadError" );

        if ( ignoreDownloadErrorParam != null )
        {
            this.ignoreDownloadError = Boolean.parseBoolean( ignoreDownloadErrorParam );
        }

        boolean verbatim = true;

        String verbatimParam = (String) request.getParameter( "verbatim" );

        if ( verbatimParam != null && !"".equals( verbatimParam ) )
        {
            verbatim = Boolean.valueOf( verbatimParam ).booleanValue();
        }

        String encoding = (String) request.getParameter( "encoding" );

        URL url;

        if ( !StringUtils.isEmpty( urlParam ) )
        {
            try
            {
                url = new URL( urlParam );
            }
            catch ( MalformedURLException e )
            {
                throw new IllegalArgumentException( urlParam + " is a malformed URL" );
            }
        }
        else if ( !StringUtils.isEmpty( fileParam ) )
        {
            File f = new File( fileParam );

            if ( !f.isAbsolute() )
            {
                f = new File( request.getBasedir(), fileParam );
            }

            try
            {
                url = f.toURI().toURL();
            }
            catch ( MalformedURLException e )
            {
                throw new IllegalArgumentException( fileParam + " is a malformed URL" );
            }
        }
        else
        {
            throw new IllegalArgumentException( "Either the 'url' or the 'file' param has to be given." );
        }

        StringBuffer snippet;

        try
        {
            snippet = getSnippet( url, encoding, id );
        }
        catch ( IOException e )
        {
            throw new MacroExecutionException( "Error reading snippet", e );
        }

        if ( verbatim )
        {
            sink.verbatim( SinkEventAttributeSet.BOXED );

            sink.text( snippet.toString() );

            sink.verbatim_();
        }
        else
        {
            sink.rawText( snippet.toString() );
        }
    }

    /**
     * Return a snippet of the given url.
     *
     * @param url The URL to parse.
     * @param encoding The encoding of the URL to parse.
     * @param id  The id of the snippet.
     * @return The snippet.
     * @throws IOException if something goes wrong.
     */
    private StringBuffer getSnippet( URL url, String encoding, String id )
        throws IOException
    {
        StringBuffer result;

        String cachedSnippet = getCachedSnippet( url, id );

        if ( cachedSnippet != null )
        {
            result = new StringBuffer( cachedSnippet );

            if ( debug )
            {
                result.append( "(Served from cache)" );
            }
        }
        else
        {
            try
            {
                result = new SnippetReader( url, encoding ).readSnippet( id );
                cacheSnippet( url, id, result.toString() );
                if ( debug )
                {
                    result.append( "(Fetched from url, cache content " ).append( cache ).append( ")" );
                }
            }
            catch ( IOException e )
            {
                if ( ignoreDownloadError )
                {
                    getLog().debug( "IOException which reading " + url + ": " + e );
                    result =
                        new StringBuffer( "Error during retrieving content skip as ignoreDownloadError activated." );
                }
                else
                {
                    throw e;
                }
            }
        }
        return result;
    }

    /**
     * Return a snippet from the cache.
     *
     * @param url The URL to parse.
     * @param id  The id of the snippet.
     * @return The snippet.
     */
    private String getCachedSnippet( URL url, String id )
    {
        if ( isCacheTimedout( url, id ) )
        {
            removeFromCache( url, id );
        }
        return cache.get( globalSnippetId( url, id ) );
    }

    /**
     * Return true if the snippet has been cached longer than
     * the current timeout.
     *
     * @param url The URL to parse.
     * @param id  The id of the snippet.
     * @return True if timeout exceeded.
     */
    boolean isCacheTimedout( URL url, String id )
    {
        return timeInCache( url, id ) >= timeout;
    }

    /**
     * Return the time the snippet has been cached.
     *
     * @param url The URL to parse.
     * @param id  The id of the snippet.
     * @return The cache time.
     */
    long timeInCache( URL url, String id )
    {
        return System.currentTimeMillis() - getTimeCached( url, id );
    }

    /**
     * Return the absolute value of when the snippet has been cached.
     *
     * @param url The URL to parse.
     * @param id  The id of the snippet.
     * @return The cache time.
     */
    long getTimeCached( URL url, String id )
    {
        String globalId = globalSnippetId( url, id );

        return timeCached.containsKey( globalId ) ? timeCached.get( globalId ).longValue() : 0;
    }

    /**
     * Removes the snippet from the cache.
     *
     * @param url The URL to parse.
     * @param id  The id of the snippet.
     */
    private void removeFromCache( URL url, String id )
    {
        String globalId = globalSnippetId( url, id );

        timeCached.remove( globalId );

        cache.remove( globalId );
    }

    /**
     * Return a global identifier for the snippet.
     *
     * @param url The URL to parse.
     * @param id  The id of the snippet.
     * @return An identifier, concatenated url and id,
     *         or just url.toString() if id is empty or null.
     */
    private String globalSnippetId( URL url, String id )
    {
        if ( StringUtils.isEmpty( id ) )
        {
            return url.toString();
        }

        return url + " " + id;
    }

    /**
     * Puts the given snippet into the cache.
     *
     * @param url     The URL to parse.
     * @param id      The id of the snippet.
     * @param content The content of the snippet.
     */
    public void cacheSnippet( URL url, String id, String content )
    {
        cache.put( globalSnippetId( url, id ), content );

        timeCached.put( globalSnippetId( url, id ), Long.valueOf( System.currentTimeMillis() ) );
    }

    /**
     * Set the cache timeout.
     *
     * @param time The timeout to set.
     */
    public void setCacheTimeout( int time )
    {
        this.timeout = time;
    }
}
