/*
    JSPWiki - a JSP-based WikiWiki clone.

    Copyright (C) 2001-2002 Janne Jalkanen (Janne.Jalkanen@iki.fi)

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation; either version 2.1 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
package com.ecyrd.jspwiki.attachment;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

import com.ecyrd.jspwiki.*;
import com.ecyrd.jspwiki.parser.MarkupParser;
import com.ecyrd.jspwiki.providers.ProviderException;
import com.ecyrd.jspwiki.providers.WikiAttachmentProvider;
import com.ecyrd.jspwiki.util.ClassUtil;
import com.opensymphony.oscache.base.Cache;
import com.opensymphony.oscache.base.NeedsRefreshException;

/**
 *  Provides facilities for handling attachments.  All attachment
 *  handling goes through this class.
 *  <p>
 *  The AttachmentManager provides a facade towards the current WikiAttachmentProvider
 *  that is in use.  It is created by the WikiEngine as a singleton object, and
 *  can be requested through the WikiEngine.
 *
 *  @author Janne Jalkanen
 *  @since 1.9.28
 */
public class AttachmentManager
{
    /**
     *  The property name for defining the attachment provider class name.
     */
    public static final String  PROP_PROVIDER = "jspwiki.attachmentProvider";

    /**
     *  The maximum size of attachments that can be uploaded.
     */
    public static final String  PROP_MAXSIZE  = "jspwiki.attachment.maxsize";

    /**
     *  A space-separated list of attachment types which can be uploaded
     */
    public static final String PROP_ALLOWEDEXTENSIONS    = "jspwiki.attachment.allowed";

    /**
     *  A space-separated list of attachment types which cannot be uploaded
     */
    public static final String PROP_FORDBIDDENEXTENSIONS = "jspwiki.attachment.forbidden";

    static Logger log = Logger.getLogger( AttachmentManager.class );
    private WikiAttachmentProvider m_provider;
    private WikiEngine             m_engine;

    /**
     *  Creates a new AttachmentManager.  Note that creation will never fail,
     *  but it's quite likely that attachments do not function.
     *  <p>
     *  <b>DO NOT CREATE</b> an AttachmentManager on your own, unless you really
     *  know what you're doing.  Just use WikiEngine.getAttachmentManager() if
     *  you're making a module for JSPWiki.
     *
     *  @param engine The wikiengine that owns this attachment manager.
     *  @param props  A list of properties from which the AttachmentManager will seek
     *  its configuration.  Typically this is the "jspwiki.properties".
     */

    // FIXME: Perhaps this should fail somehow.
    public AttachmentManager( WikiEngine engine, Properties props )
    {
        String classname;

        m_engine = engine;


        //
        //  If user wants to use a cache, then we'll use the CachingProvider.
        //
        boolean useCache = "true".equals(props.getProperty( PageManager.PROP_USECACHE ));

        if( useCache )
        {
            classname = "com.ecyrd.jspwiki.providers.CachingAttachmentProvider";
        }
        else
        {
            classname = props.getProperty( PROP_PROVIDER );
        }

        //
        //  If no class defined, then will just simply fail.
        //
        if( classname == null )
        {
            log.info( "No attachment provider defined - disabling attachment support." );
            return;
        }

        //
        //  Create and initialize the provider.
        //
        try
        {
            Class providerclass = ClassUtil.findClass( "com.ecyrd.jspwiki.providers",
                                                       classname );

            m_provider = (WikiAttachmentProvider)providerclass.newInstance();

            m_provider.initialize( m_engine, props );
        }
        catch( ClassNotFoundException e )
        {
            log.error( "Attachment provider class not found",e);
        }
        catch( InstantiationException e )
        {
            log.error( "Attachment provider could not be created", e );
        }
        catch( IllegalAccessException e )
        {
            log.error( "You may not access the attachment provider class", e );
        }
        catch( NoRequiredPropertyException e )
        {
            log.error( "Attachment provider did not find a property that it needed: "+e.getMessage(), e );
            m_provider = null; // No, it did not work.
        }
        catch( IOException e )
        {
            log.error( "Attachment provider reports IO error", e );
            m_provider = null;
        }
    }

    /**
     *  Returns true, if attachments are enabled and running.
     *
     *  @return A boolean value indicating whether attachment functionality is enabled.
     */
    public boolean attachmentsEnabled()
    {
        return m_provider != null;
    }

    /**
     *  Gets info on a particular attachment, latest version.
     *
     *  @param name A full attachment name.
     *  @return Attachment, or null, if no such attachment exists.
     *  @throws ProviderException If something goes wrong.
     */
    public Attachment getAttachmentInfo( String name )
        throws ProviderException
    {
        return getAttachmentInfo( name, WikiProvider.LATEST_VERSION );
    }

    /**
     *  Gets info on a particular attachment with the given version.
     *
     *  @param name A full attachment name.
     *  @param version A version number.
     *  @return Attachment, or null, if no such attachment or version exists.
     *  @throws ProviderException If something goes wrong.
     */

    public Attachment getAttachmentInfo( String name, int version )
        throws ProviderException
    {
        if( name == null )
        {
            return null;
        }

        return getAttachmentInfo( null, name, version );
    }

    /**
     *  Figures out the full attachment name from the context and
     *  attachment name.
     *
     *  @param context The current WikiContext
     *  @param attachmentname The file name of the attachment.
     *  @return Attachment, or null, if no such attachment exists.
     *  @throws ProviderException If something goes wrong.
     */

    public Attachment getAttachmentInfo( WikiContext context,
                                         String attachmentname )
        throws ProviderException
    {
        return getAttachmentInfo( context, attachmentname, WikiProvider.LATEST_VERSION );
    }

    /**
     *  Figures out the full attachment name from the context and
     *  attachment name.
     *
     *  @param context The current WikiContext
     *  @param attachmentname The file name of the attachment.
     *  @param version A particular version.
     *  @return Attachment, or null, if no such attachment or version exists.
     *  @throws ProviderException If something goes wrong.
     */

    public Attachment getAttachmentInfo( WikiContext context,
                                         String attachmentname,
                                         int version )
        throws ProviderException
    {
        if( m_provider == null )
        {
            return null;
        }

        WikiPage currentPage = null;

        if( context != null )
        {
            currentPage = context.getPage();
        }

        //
        //  Figure out the parent page of this attachment.  If we can't find it,
        //  we'll assume this refers directly to the attachment.
        //
        int cutpt = attachmentname.lastIndexOf('/');

        if( cutpt != -1 )
        {
            String parentPage = attachmentname.substring(0,cutpt);
            parentPage = MarkupParser.cleanLink( parentPage );
            attachmentname = attachmentname.substring(cutpt+1);

            // If we for some reason have an empty parent page name;
            // this can't be an attachment
            if(parentPage.length() == 0) return null;

            currentPage = m_engine.getPage( parentPage );

            //
            // Go check for legacy name
            //
            // FIXME: This should be resolved using CommandResolver,
            //        not this adhoc way.  This also assumes that the
            //        legacy charset is a subset of the full allowed set.
            if( currentPage == null )
            {
                currentPage = m_engine.getPage( MarkupParser.wikifyLink( parentPage ) );
            }
        }

        //
        //  If the page cannot be determined, we cannot possibly find the
        //  attachments.
        //
        if( currentPage == null || currentPage.getName().length() == 0 )
        {
            return null;
        }

        // System.out.println("Seeking info on "+currentPage+"::"+attachmentname);

        //
        //  Finally, figure out whether this is a real attachment or a generated
        //  attachment.
        //
        Attachment att;

        att = getDynamicAttachment( currentPage.getName()+"/"+attachmentname );

        if( att == null )
        {
            att = m_provider.getAttachmentInfo( currentPage, attachmentname, version );
        }

        return att;
    }

    /**
     *  Returns the list of attachments associated with a given wiki page.
     *  If there are no attachments, returns an empty Collection.
     *
     *  @param wikipage The wiki page from which you are seeking attachments for.
     *  @return a valid collection of attachments.
     *  @throws ProviderException If there was something wrong in the backend.
     */

    // FIXME: This API should be changed to return a List.
    public Collection listAttachments( WikiPage wikipage )
        throws ProviderException
    {
        if( m_provider == null )
        {
            return new ArrayList();
        }

        Collection atts = m_provider.listAttachments( wikipage );

        //
        //  This is just a sanity check; all of our providers return a Collection.
        //
        if( atts instanceof List )
        {
            Collections.sort( (List) atts );
        }

        return atts;
    }

    /**
     *  Returns true, if the page has any attachments at all.  This is
     *  a convinience method.
     *
     *
     *  @param wikipage The wiki page from which you are seeking attachments for.
     *  @return True, if the page has attachments, else false.
     */
    public boolean hasAttachments( WikiPage wikipage )
    {
        try
        {
            return listAttachments( wikipage ).size() > 0;
        }
        catch( Exception e ) {}

        return false;
    }

    /**
     *  Finds a (real) attachment from the repository as a stream.
     *
     *  @param att Attachment
     *  @return An InputStream to read from.  May return null, if
     *          attachments are disabled.
     *  @throws IOException If the stream cannot be opened
     *  @throws ProviderException If the backend fails due to some other reason.
     */
    public InputStream getAttachmentStream( Attachment att )
        throws IOException,
               ProviderException
    {
        return getAttachmentStream( null, att );
    }

    /**
     *  Returns an attachment stream using the particular WikiContext.  This method
     *  should be used instead of getAttachmentStream(Attachment), since it also allows
     *  the DynamicAttachments to function.
     *
     *  @param ctx The Wiki Context
     *  @param att The Attachment to find
     *  @return An InputStream.  May return null, if attachments are disabled.  You must
     *          take care of closing it.
     *  @throws ProviderException If the backend fails due to some reason
     *  @throws IOException If the stream cannot be opened
     */
    public InputStream getAttachmentStream( WikiContext ctx, Attachment att )
        throws ProviderException, IOException
    {
        if( m_provider == null )
        {
            return null;
        }

        if( att instanceof DynamicAttachment )
        {
            return ((DynamicAttachment)att).getProvider().getAttachmentData( ctx, att );
        }

        return m_provider.getAttachmentData( att );
    }

    private Cache m_dynamicAttachments = new Cache( true, false, false );

    /**
     *  Stores a dynamic attachment.  Unlike storeAttachment(), this just stores
     *  the attachment in the memory.
     *
     *  @param ctx A WikiContext
     *  @param att An attachment to store
     */
    public void storeDynamicAttachment( WikiContext ctx, DynamicAttachment att )
    {
        m_dynamicAttachments.putInCache( att.getName(),  att );
    }

    /**
     *  Finds a DynamicAttachment.  Normally, you should just use getAttachmentInfo(),
     *  since that will find also DynamicAttachments.
     *
     *  @param name The name of the attachment to look for
     *  @return An Attachment, or null.
     *  @see #getAttachmentInfo(String)
     */

    public DynamicAttachment getDynamicAttachment( String name )
    {
        try
        {
            return (DynamicAttachment) m_dynamicAttachments.getFromCache( name );
        }
        catch( NeedsRefreshException e )
        {
            //
            //  Remove from cache, it has expired.
            //
            m_dynamicAttachments.putInCache( name, null );

            return null;
        }
    }

    /**
     *  Stores an attachment that lives in the given file.
     *  If the attachment did not exist previously, this method
     *  will create it.  If it did exist, it stores a new version.
     *
     *  @param att Attachment to store this under.
     *  @param source A file to read from.
     *
     *  @throws IOException If writing the attachment failed.
     *  @throws ProviderException If something else went wrong.
     */
    public void storeAttachment( Attachment att, File source )
        throws IOException,
               ProviderException
    {
        FileInputStream in = null;

        try
        {
            in = new FileInputStream( source );
            storeAttachment( att, in );
        }
        finally
        {
            if( in != null ) in.close();
        }
    }

    /**
     *  Stores an attachment directly from a stream.
     *  If the attachment did not exist previously, this method
     *  will create it.  If it did exist, it stores a new version.
     *
     *  @param att Attachment to store this under.
     *  @param in  InputStream from which the attachment contents will be read.
     *
     *  @throws IOException If writing the attachment failed.
     *  @throws ProviderException If something else went wrong.
     */
    public void storeAttachment( Attachment att, InputStream in )
        throws IOException,
               ProviderException
    {
        if( m_provider == null )
        {
            return;
        }

        //
        //  Checks if the actual, real page exists without any modifications
        //  or aliases.  We cannot store an attachment to a non-existant page.
        //
        if( !m_engine.getPageManager().pageExists( att.getParentName() ) )
        {
            throw new ProviderException("Parent page does not exist");
        }
        
        m_provider.putAttachmentData( att, in );

        m_engine.getReferenceManager().updateReferences( att.getName(),
                                                         new java.util.Vector() );

        WikiPage parent = new WikiPage( m_engine, att.getParentName() );
        m_engine.updateReferences( parent );

        m_engine.getSearchManager().reindexPage( att );
    }

    /**
     *  Returns a list of versions of the attachment.
     *
     *  @param attachmentName A fully qualified name of the attachment.
     *
     *  @return A list of Attachments.  May return null, if attachments are
     *          disabled.
     *  @throws ProviderException If the provider fails for some reason.
     */
    public List getVersionHistory( String attachmentName )
        throws ProviderException
    {
        if( m_provider == null )
        {
            return null;
        }

        Attachment att = getAttachmentInfo( (WikiContext)null, attachmentName );

        if( att != null )
        {
            return m_provider.getVersionHistory( att );
        }

        return null;
    }

    /**
     *  Returns a collection of Attachments, containing each and every attachment
     *  that is in this Wiki.
     *
     *  @return A collection of attachments.  If attachments are disabled, will
     *          return an empty collection.
     *  @throws ProviderException If something went wrong with the backend
     */
    public Collection getAllAttachments()
        throws ProviderException
    {
        if( attachmentsEnabled() )
        {
            return m_provider.listAllChanged( new Date(0L) );
        }

        return new ArrayList();
    }

    /**
     *  Returns the current attachment provider.
     *
     *  @return The current provider.  May be null, if attachments are disabled.
     */
    public WikiAttachmentProvider getCurrentProvider()
    {
        return m_provider;
    }

    /**
     *  Deletes the given attachment version.
     *
     *  @param att The attachment to delete
     *  @throws ProviderException If something goes wrong with the backend.
     */
    public void deleteVersion( Attachment att )
        throws ProviderException
    {
        if( m_provider == null ) return;

        m_provider.deleteVersion( att );
    }

    /**
     *  Deletes all versions of the given attachment.
     *  @param att The Attachment to delete.
     *  @throws ProviderException if something goes wrong with the backend.
     */
    // FIXME: Should also use events!
    public void deleteAttachment( Attachment att )
        throws ProviderException
    {
        if( m_provider == null ) return;

        m_provider.deleteAttachment( att );

        m_engine.getSearchManager().pageRemoved( att );

        m_engine.getReferenceManager().clearPageEntries( att.getName() );

    }

    /**
     *  Validates the filename and makes sure it is legal.  It trims and splits
     *  and replaces bad characters.
     *  
     *  @param filename
     *  @return A validated name with annoying characters replaced.
     *  @throws WikiException If the filename is not legal (e.g. empty)
     */
    static String validateFileName( String filename )
        throws WikiException
    {
        if( filename == null || filename.trim().length() == 0 )
        {
            AttachmentServlet.log.error("Empty file name given.");
    
            throw new WikiException("Empty file name given.");
        }
    
        //
        //  Should help with IE 5.22 on OSX
        //
        filename = filename.trim();

        // If file name ends with .jsp or .jspf, the user is being naughty!
        if( filename.toLowerCase().endsWith( ".jsp" ) || filename.toLowerCase().endsWith(".jspf") )
        {
            log.info( "Attempt to upload a file with a .jsp/.jspf extension.  In certain cases this" +
            		" can trigger unwanted security side effects, so we're preventing it." );
            
            throw new WikiException( "Unwanted file name." );
        }
    
        //
        //  Some browser send the full path info with the filename, so we need
        //  to remove it here by simply splitting along slashes and then taking the path.
        //
        
        String[] splitpath = filename.split( "[/\\\\]" );
        filename = splitpath[splitpath.length-1];
        
        //
        //  Remove any characters that might be a problem. Most
        //  importantly - characters that might stop processing
        //  of the URL.
        //
        filename = StringUtils.replaceChars( filename, "#?\"'", "____" );
    
        return filename;
    }
}
