/*
    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.
 */
package org.apache.wiki.providers;

import org.apache.log4j.Logger;
import org.apache.wiki.InternalWikiException;
import org.apache.wiki.WikiPage;
import org.apache.wiki.api.core.Engine;
import org.apache.wiki.api.core.Page;
import org.apache.wiki.api.exceptions.NoRequiredPropertyException;
import org.apache.wiki.api.exceptions.ProviderException;
import org.apache.wiki.api.providers.PageProvider;
import org.apache.wiki.api.providers.WikiProvider;
import org.apache.wiki.util.FileUtil;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Properties;

/**
 *  Provides a simple directory based repository for Wiki pages.
 *  Pages are held in a directory structure:
 *  <PRE>
 *    Main.txt
 *    Foobar.txt
 *    OLD/
 *       Main/
 *          1.txt
 *          2.txt
 *          page.properties
 *       Foobar/
 *          page.properties
 *  </PRE>
 *
 *  In this case, "Main" has three versions, and "Foobar" just one version.
 *  <P>
 *  The properties file contains the necessary metainformation (such as author)
 *  information of the page.  DO NOT MESS WITH IT!
 *
 *  <P>
 *  All files have ".txt" appended to make life easier for those
 *  who insist on using Windows or other software which makes assumptions
 *  on the files contents based on its name.
 *
 */
public class VersioningFileProvider extends AbstractFileProvider {

    private static final Logger     log = Logger.getLogger(VersioningFileProvider.class);

    /** Name of the directory where the old versions are stored. */
    public static final String      PAGEDIR      = "OLD";

    /** Name of the property file which stores the metadata. */
    public static final String      PROPERTYFILE = "page.properties";

    private CachedProperties        m_cachedProperties;

    /**
     *  {@inheritDoc}
     */
    @Override
    public void initialize( final Engine engine, final Properties properties ) throws NoRequiredPropertyException, IOException {
        super.initialize( engine, properties );
        // some additional sanity checks :
        final File oldpages = new File( getPageDirectory(), PAGEDIR );
        if( !oldpages.exists() ) {
            if( !oldpages.mkdirs() ) {
                throw new IOException( "Failed to create page version directory " + oldpages.getAbsolutePath() );
            }
        } else {
            if( !oldpages.isDirectory() ) {
                throw new IOException( "Page version directory is not a directory: " + oldpages.getAbsolutePath() );
            }
            if( !oldpages.canWrite() ) {
                throw new IOException( "Page version directory is not writable: " + oldpages.getAbsolutePath() );
            }
        }
        log.info( "Using directory " + oldpages.getAbsolutePath() + " for storing old versions of pages" );
    }

    /**
     *  Returns the directory where the old versions of the pages
     *  are being kept.
     */
    private File findOldPageDir( final String page ) {
        if( page == null ) {
            throw new InternalWikiException( "Page may NOT be null in the provider!" );
        }
        final File oldpages = new File( getPageDirectory(), PAGEDIR );
        return new File( oldpages, mangleName( page ) );
    }

    /**
     *  Goes through the repository and decides which version is the newest one in that directory.
     *
     *  @return Latest version number in the repository, or -1, if there is no page in the repository.
     */

    // FIXME: This is relatively slow.
    /*
    private int findLatestVersion( String page )
    {
        File pageDir = findOldPageDir( page );

        String[] pages = pageDir.list( new WikiFileFilter() );

        if( pages == null )
        {
            return -1; // No such thing found.
        }

        int version = -1;

        for( int i = 0; i < pages.length; i++ )
        {
            int cutpoint = pages[i].indexOf( '.' );
            if( cutpoint > 0 )
            {
                String pageNum = pages[i].substring( 0, cutpoint );

                try
                {
                    int res = Integer.parseInt( pageNum );

                    if( res > version )
                    {
                        version = res;
                    }
                }
                catch( NumberFormatException e ) {} // It's okay to skip these.
            }
        }

        return version;
    }
*/
    private int findLatestVersion( final String page ) {
        int version = -1;

        try {
            final Properties props = getPageProperties( page );

            for( final Object o : props.keySet() ) {
                final String key = ( String )o;
                if( key.endsWith( ".author" ) ) {
                    final int cutpoint = key.indexOf( '.' );
                    if( cutpoint > 0 ) {
                        final String pageNum = key.substring( 0, cutpoint );

                        try {
                            final int res = Integer.parseInt( pageNum );

                            if( res > version ) {
                                version = res;
                            }
                        } catch( final NumberFormatException e ) {
                        } // It's okay to skip these.
                    }
                }
            }
        } catch( final IOException e ) {
            log.error( "Unable to figure out latest version - dying...", e );
        }

        return version;
    }

    /**
     *  Reads page properties from the file system.
     */
    private Properties getPageProperties( final String page ) throws IOException {
        final File propertyFile = new File( findOldPageDir(page), PROPERTYFILE );
        if( propertyFile.exists() ) {
            final long lastModified = propertyFile.lastModified();

            //
            //   The profiler showed that when calling the history of a page the propertyfile
            //   was read just as much times as there were versions of that file. The loading
            //   of a propertyfile is a cpu-intensive job. So now hold on to the last propertyfile
            //   read because the next method will with a high probability ask for the same propertyfile.
            //   The time it took to show a historypage with 267 versions dropped with 300%.
            //

            CachedProperties cp = m_cachedProperties;

            if( cp != null && cp.m_page.equals( page ) && cp.m_lastModified == lastModified ) {
                return cp.m_props;
            }

            try( final InputStream in = new BufferedInputStream(new FileInputStream( propertyFile ) ) ) {
                final Properties props = new Properties();
                props.load( in );
                cp = new CachedProperties( page, props, lastModified );
                m_cachedProperties = cp; // Atomic

                return props;
            }
        }

        return new Properties(); // Returns an empty object
    }

    /**
     *  Writes the page properties back to the file system.
     *  Note that it WILL overwrite any previous properties.
     */
    private void putPageProperties( final String page, final Properties properties ) throws IOException {
        final File propertyFile = new File( findOldPageDir(page), PROPERTYFILE );
        try( final OutputStream out = new FileOutputStream( propertyFile ) ) {
            properties.store( out, " JSPWiki page properties for "+page+". DO NOT MODIFY!" );
        }

        // The profiler showed the probability was very high that when  calling for the history of
        // a page the propertyfile would be read as much times as there were versions of that file.
        // It is statistically likely the propertyfile will be examined many times before it is updated.
        final CachedProperties cp = new CachedProperties( page, properties, propertyFile.lastModified() );
        m_cachedProperties = cp; // Atomic
    }

    /**
     *  Figures out the real version number of the page and also checks for its existence.
     *
     *  @throws NoSuchVersionException if there is no such version.
     */
    private int realVersion( final String page, final int requestedVersion ) throws NoSuchVersionException {
        //  Quickly check for the most common case.
        if( requestedVersion == WikiProvider.LATEST_VERSION ) {
            return -1;
        }

        final int latest = findLatestVersion(page);

        if( requestedVersion == latest || (requestedVersion == 1 && latest == -1 ) ) {
            return -1;
        } else if( requestedVersion <= 0 || requestedVersion > latest ) {
            throw new NoSuchVersionException( "Requested version " + requestedVersion + ", but latest is " + latest );
        }

        return requestedVersion;
    }

    /**
     *  {@inheritDoc}
     */
    @Override
    public synchronized String getPageText( final String page, int version ) throws ProviderException {
        final File dir = findOldPageDir( page );

        version = realVersion( page, version );
        if( version == -1 ) {
            // We can let the FileSystemProvider take care of these requests.
            return super.getPageText( page, PageProvider.LATEST_VERSION );
        }

        final File pageFile = new File( dir, ""+version+FILE_EXT );
        if( !pageFile.exists() ) {
            throw new NoSuchVersionException("Version "+version+"does not exist.");
        }

        return readFile( pageFile );
    }


    // FIXME: Should this really be here?
    private String readFile( final File pagedata ) throws ProviderException {
        String result = null;
        if( pagedata.exists() ) {
            if( pagedata.canRead() ) {
                try( final InputStream in = new FileInputStream( pagedata ) ) {
                    result = FileUtil.readContents( in, m_encoding );
                } catch( final IOException e ) {
                    log.error("Failed to read", e);
                    throw new ProviderException("I/O error: "+e.getMessage());
                }
            } else {
                log.warn("Failed to read page from '"+pagedata.getAbsolutePath()+"', possibly a permissions problem");
                throw new ProviderException("I cannot read the requested page.");
            }
        } else {
            // This is okay.
            // FIXME: is it?
            log.info("New page");
        }

        return result;
    }

    // FIXME: This method has no rollback whatsoever.

    /*
      This is how the page directory should look like:

         version    pagedir       olddir
          none       empty         empty
           1         Main.txt (1)  empty
           2         Main.txt (2)  1.txt
           3         Main.txt (3)  1.txt, 2.txt
    */
    /**
     *  {@inheritDoc}
     */
    @Override
    public synchronized void putPageText( final Page page, final String text ) throws ProviderException {
        // This is a bit complicated.  We'll first need to copy the old file to be the newest file.
        final int  latest  = findLatestVersion( page.getName() );
        final File pageDir = findOldPageDir( page.getName() );
        if( !pageDir.exists() ) {
            pageDir.mkdirs();
        }

        try {
            // Copy old data to safety, if one exists.
            final File oldFile = findPage( page.getName() );

            // Figure out which version should the old page be? Numbers should always start at 1.
            // "most recent" = -1 ==> 1
            // "first"       = 1  ==> 2
            int versionNumber = (latest > 0) ? latest : 1;
            final boolean firstUpdate = (versionNumber == 1);

            if( oldFile != null && oldFile.exists() ) {
                final File pageFile = new File( pageDir, versionNumber + FILE_EXT );
                try( final InputStream in = new BufferedInputStream( new FileInputStream( oldFile ) );
                     final OutputStream out = new BufferedOutputStream( new FileOutputStream( pageFile ) ) ) {
                    FileUtil.copyContents( in, out );

                    // We need also to set the date, since we rely on this.
                    pageFile.setLastModified( oldFile.lastModified() );

                    // Kludge to make the property code to work properly.
                    versionNumber++;
                }
            }

            //  Let superclass handler writing data to a new version.
            super.putPageText( page, text );

            //  Finally, write page version data.
            // FIXME: No rollback available.
            final Properties props = getPageProperties( page.getName() );

            String authorFirst = null;
            // if the following file exists, we are NOT migrating from FileSystemProvider
            final File pagePropFile = new File(getPageDirectory() + File.separator + PAGEDIR + File.separator + mangleName(page.getName()) + File.separator + "page" + FileSystemProvider.PROP_EXT);
            if( firstUpdate && ! pagePropFile.exists() ) {
                // we might not yet have a versioned author because the old page was last maintained by FileSystemProvider
                final Properties props2 = getHeritagePageProperties( page.getName() );

                // remember the simulated original author (or something) in the new properties
                authorFirst = props2.getProperty( "1.author", "unknown" );
                props.setProperty( "1.author", authorFirst );
            }

            String newAuthor = page.getAuthor();
            if ( newAuthor == null ) {
                newAuthor = ( authorFirst != null ) ? authorFirst : "unknown";
            }
            page.setAuthor(newAuthor);
            props.setProperty( versionNumber + ".author", newAuthor );

            final String changeNote = page.getAttribute( Page.CHANGENOTE );
            if( changeNote != null ) {
                props.setProperty( versionNumber + ".changenote", changeNote );
            }

            // Get additional custom properties from page and add to props
            getCustomProperties( page, props );
            putPageProperties( page.getName(), props );
        } catch( final IOException e ) {
            log.error( "Saving failed", e );
            throw new ProviderException("Could not save page text: "+e.getMessage());
        }
    }

    /**
     *  {@inheritDoc}
     */
    @Override
    public Page getPageInfo( final String page, final int version ) throws ProviderException {
        final int latest = findLatestVersion( page );
        final int realVersion;

        Page p = null;

        if( version == PageProvider.LATEST_VERSION || version == latest || (version == 1 && latest == -1) ) {
            //
            // Yes, we need to talk to the top level directory to get this version.
            //
            // I am listening to Press Play On Tape's guitar version of the good old C64 "Wizardry" -tune at this moment.
            // Oh, the memories...
            //
            realVersion = (latest >= 0) ? latest : 1;

            p = super.getPageInfo( page, PageProvider.LATEST_VERSION );

            if( p != null ) {
                p.setVersion( realVersion );
            }
        } else {
            // The file is not the most recent, so we'll need to find it from the deep trenches of the "OLD" directory structure.
            realVersion = version;
            final File dir = findOldPageDir( page );
            if( !dir.exists() || !dir.isDirectory() ) {
                return null;
            }

            final File file = new File( dir, version + FILE_EXT );
            if( file.exists() ) {
                p = new WikiPage( m_engine, page );

                p.setLastModified( new Date( file.lastModified() ) );
                p.setVersion( version );
            }
        }

        //  Get author and other metadata information (Modification date has already been set.)
        if( p != null ) {
            try {
                final Properties props = getPageProperties( page );
                String author = props.getProperty( realVersion + ".author" );
                if( author == null ) {
                    // we might not have a versioned author because the old page was last maintained by FileSystemProvider
                    final Properties props2 = getHeritagePageProperties( page );
                    author = props2.getProperty( Page.AUTHOR );
                }
                if( author != null ) {
                    p.setAuthor( author );
                }

                final String changenote = props.getProperty( realVersion + ".changenote" );
                if( changenote != null ) {
                    p.setAttribute( Page.CHANGENOTE, changenote );
                }

                // Set the props values to the page attributes
                setCustomProperties( p, props );
            } catch( final IOException e ) {
                log.error( "Cannot get author for page" + page + ": ", e );
            }
        }

        return p;
    }

    /**
     *  {@inheritDoc}
     */
    @Override
    public boolean pageExists( final String pageName, final int version ) {
        if (version == PageProvider.LATEST_VERSION || version == findLatestVersion( pageName ) ) {
            return pageExists(pageName);
        }

        final File dir = findOldPageDir( pageName );
        if( !dir.exists() || !dir.isDirectory() ) {
            return false;
        }

        return new File( dir, version + FILE_EXT ).exists();
    }

    /**
     *  {@inheritDoc}
     */
     // FIXME: Does not get user information.
    @Override
    public List< Page > getVersionHistory( final String page ) throws ProviderException {
        final ArrayList< Page > list = new ArrayList<>();
        final int latest = findLatestVersion( page );
        for( int i = latest; i > 0; i-- ) {
            final Page info = getPageInfo( page, i );
            if( info != null ) {
                list.add( info );
            }
        }

        return list;
    }

    /*
     * Support for migration of simple properties created by the FileSystemProvider when coming under Versioning management.
     * Simulate an initial version.
     */
    private Properties getHeritagePageProperties( final String page ) throws IOException {
        final File propertyFile = new File( getPageDirectory(), mangleName( page ) + FileSystemProvider.PROP_EXT );
        if ( propertyFile.exists() ) {
            final long lastModified = propertyFile.lastModified();

            CachedProperties cp = m_cachedProperties;
            if ( cp != null && cp.m_page.equals(page) && cp.m_lastModified == lastModified ) {
                return cp.m_props;
            }

            try( final InputStream in = new BufferedInputStream( new FileInputStream( propertyFile ) ) ) {
                final Properties props = new Properties();
                props.load( in );

                final String originalAuthor = props.getProperty( Page.AUTHOR );
                if ( originalAuthor.length() > 0 ) {
                    // simulate original author as if already versioned but put non-versioned property in special cache too
                    props.setProperty( "1.author", originalAuthor );

                    // The profiler showed the probability was very high that when calling for the history of a page the
                    // propertyfile would be read as much times as there were versions of that file. It is statistically
                    // likely the propertyfile will be examined many times before it is updated.
                    cp = new CachedProperties( page, props, propertyFile.lastModified() );
                    m_cachedProperties = cp; // Atomic
                }

                return props;
            }
        }

        return new Properties(); // Returns an empty object
    }

    /**
     *  Removes the relevant page directory under "OLD" -directory as well, but does not remove any extra subdirectories from it.
     *  It will only touch those files that it thinks to be WikiPages.
     *
     *  @param page {@inheritDoc}
     *  @throws {@inheritDoc}
     */
    // FIXME: Should log errors.
    @Override
    public void deletePage( final String page ) throws ProviderException {
        super.deletePage( page );
        final File dir = findOldPageDir( page );
        if( dir.exists() && dir.isDirectory() ) {
            final File[] files = dir.listFiles( new WikiFileFilter() );
            for( int i = 0; i < files.length; i++ ) {
                files[ i ].delete();
            }

            final File propfile = new File( dir, PROPERTYFILE );
            if( propfile.exists() ) {
                propfile.delete();
            }

            dir.delete();
        }
    }

    /**
     *  {@inheritDoc}
     *
     *  Deleting versions has never really worked, JSPWiki assumes that version histories are "not gappy". Using deleteVersion() is
     *  definitely not recommended.
     */
    @Override
    public void deleteVersion( final String page, final int version ) throws ProviderException {
        final File dir = findOldPageDir( page );
        int latest = findLatestVersion( page );
        if( version == PageProvider.LATEST_VERSION ||
            version == latest ||
            (version == 1 && latest == -1) ) {
            //  Delete the properties
            try {
                final Properties props = getPageProperties( page );
                props.remove( ((latest > 0) ? latest : 1)+".author" );
                putPageProperties( page, props );
            } catch( final IOException e ) {
                log.error("Unable to modify page properties",e);
                throw new ProviderException("Could not modify page properties: " + e.getMessage());
            }

            // We can let the FileSystemProvider take care of the actual deletion
            super.deleteVersion( page, PageProvider.LATEST_VERSION );

            //  Copy the old file to the new location
            latest = findLatestVersion( page );

            final File pageDir = findOldPageDir( page );
            final File previousFile = new File( pageDir, latest + FILE_EXT );
            final File pageFile = findPage(page);
            try( final InputStream in = new BufferedInputStream( new FileInputStream( previousFile ) );
                 final OutputStream out = new BufferedOutputStream( new FileOutputStream( pageFile ) ) ) {
                if( previousFile.exists() ) {
                    FileUtil.copyContents( in, out );
                    // We need also to set the date, since we rely on this.
                    pageFile.setLastModified( previousFile.lastModified() );
                }
            } catch( final IOException e ) {
                log.fatal("Something wrong with the page directory - you may have just lost data!",e);
            }

            return;
        }

        final File pageFile = new File( dir, ""+version+FILE_EXT );
        if( pageFile.exists() ) {
            if( !pageFile.delete() ) {
                log.error("Unable to delete page." + pageFile.getPath() );
            }
        } else {
            throw new NoSuchVersionException("Page "+page+", version="+version);
        }
    }

    /**
     *  {@inheritDoc}
     */
    // FIXME: This is kinda slow, we should need to do this only once.
    @Override
    public Collection< Page > getAllPages() throws ProviderException {
        final Collection< Page > pages = super.getAllPages();
        final Collection< Page > returnedPages = new ArrayList<>();
        for( final Page page : pages ) {
            final Page info = getPageInfo( page.getName(), WikiProvider.LATEST_VERSION );
            returnedPages.add( info );
        }

        return returnedPages;
    }

    /**
     *  {@inheritDoc}
     */
    @Override
    public String getProviderInfo()
    {
        return "";
    }

    /**
     *  {@inheritDoc}
     */
    @Override
    public void movePage( final String from, final String to ) {
        // Move the file itself
        final File fromFile = findPage( from );
        final File toFile = findPage( to );
        fromFile.renameTo( toFile );

        // Move any old versions
        final File fromOldDir = findOldPageDir( from );
        final File toOldDir = findOldPageDir( to );
        fromOldDir.renameTo( toOldDir );
    }

    /*
     * The profiler showed that when calling the history of a page, the propertyfile was read just as many
     * times as there were versions of that file. The loading of a propertyfile is a cpu-intensive job.
     * This Class holds onto the last propertyfile read, because the probability is high that the next call
     * will with ask for the same propertyfile. The time it took to show a historypage with 267 versions dropped
     * by 300%. Although each propertyfile in a history could be cached, there is likely to be little performance
     * gain over simply keeping the last one requested.
     */
    private static class CachedProperties {
        String m_page;
        Properties m_props;
        long m_lastModified;

        /**
         * Because a Constructor is inherently synchronised, there is no need to synchronise the arguments.
         *
         * @param pageName page name
         * @param props  Properties to use for initialization
         * @param lastModified last modified date
         */
        public CachedProperties( final String pageName, final Properties props, final long lastModified ) {
            if ( pageName == null ) {
                throw new NullPointerException ( "pageName must not be null!" );
            }
            this.m_page = pageName;
            if ( props == null ) {
                throw new NullPointerException ( "properties must not be null!" );
            }
            m_props = props;
            this.m_lastModified = lastModified;
        }
    }

}
