/*
    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.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
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.api.search.QueryItem;
import org.apache.wiki.api.search.SearchResult;
import org.apache.wiki.search.SearchMatcher;
import org.apache.wiki.search.SearchResultComparator;
import org.apache.wiki.util.FileUtil;
import org.apache.wiki.util.TextUtil;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.TreeSet;


/**
 *  Provides a simple directory based repository for Wiki pages.
 *  <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.
 *  <p>
 *  This class functions as a superclass to all file based providers.
 *
 *  @since 2.1.21.
 */
public abstract class AbstractFileProvider implements PageProvider {

    private static final Logger log = Logger.getLogger(AbstractFileProvider.class);
    private String m_pageDirectory = "/tmp/";
    protected String m_encoding;

    protected Engine m_engine;

    public static final String PROP_CUSTOMPROP_MAXLIMIT = "custom.pageproperty.max.allowed";
    public static final String PROP_CUSTOMPROP_MAXKEYLENGTH = "custom.pageproperty.key.length";
    public static final String PROP_CUSTOMPROP_MAXVALUELENGTH = "custom.pageproperty.value.length";

    public static final int DEFAULT_MAX_PROPLIMIT = 200;
    public static final int DEFAULT_MAX_PROPKEYLENGTH = 255;
    public static final int DEFAULT_MAX_PROPVALUELENGTH = 4096;

    /** This parameter limits the number of custom page properties allowed on a page */
    public static int MAX_PROPLIMIT = DEFAULT_MAX_PROPLIMIT;

    /**
     * This number limits the length of a custom page property key length. The default value here designed with future JDBC providers in mind.
     */
    public static int MAX_PROPKEYLENGTH = DEFAULT_MAX_PROPKEYLENGTH;

    /**
     * This number limits the length of a custom page property value length. The default value here designed with future JDBC providers in mind.
     */
    public static int MAX_PROPVALUELENGTH = DEFAULT_MAX_PROPVALUELENGTH;

    /** Name of the property that defines where page directories are. */
    public static final String PROP_PAGEDIR = "jspwiki.fileSystemProvider.pageDir";

    /**
     *  All files should have this extension to be recognized as JSPWiki files. We default to .txt, because that is probably easiest for
     *  Windows users, and guarantees correct handling.
     */
    public static final String FILE_EXT = ".txt";

    /** The default encoding. */
    public static final String DEFAULT_ENCODING = StandardCharsets.ISO_8859_1.toString();

    private boolean m_windowsHackNeeded = false;

    /**
     *  {@inheritDoc}
     *  @throws FileNotFoundException If the specified page directory does not exist.
     *  @throws IOException In case the specified page directory is a file, not a directory.
     */
    @Override
    public void initialize( final Engine engine, final Properties properties ) throws NoRequiredPropertyException, IOException, FileNotFoundException {
        log.debug( "Initing FileSystemProvider" );
        m_pageDirectory = TextUtil.getCanonicalFilePathProperty( properties, PROP_PAGEDIR,
                                                          System.getProperty( "user.home" ) + File.separator + "jspwiki-files" );

        final File f = new File( m_pageDirectory );

        if( !f.exists() ) {
            if( !f.mkdirs() ) {
                throw new IOException( "Failed to create page directory " + f.getAbsolutePath() + " , please check property " + PROP_PAGEDIR );
            }
        } else {
            if( !f.isDirectory() ) {
                throw new IOException( "Page directory is not a directory: " + f.getAbsolutePath() );
            }
            if( !f.canWrite() ) {
                throw new IOException( "Page directory is not writable: " + f.getAbsolutePath() );
            }
        }

        m_engine = engine;
        m_encoding = properties.getProperty( Engine.PROP_ENCODING, DEFAULT_ENCODING );
        final String os = System.getProperty( "os.name" ).toLowerCase();
        if( os.startsWith( "windows" ) || os.equals( "nt" ) ) {
            m_windowsHackNeeded = true;
        }

        MAX_PROPLIMIT = TextUtil.getIntegerProperty( properties, PROP_CUSTOMPROP_MAXLIMIT, DEFAULT_MAX_PROPLIMIT );
        MAX_PROPKEYLENGTH = TextUtil.getIntegerProperty( properties, PROP_CUSTOMPROP_MAXKEYLENGTH, DEFAULT_MAX_PROPKEYLENGTH );
        MAX_PROPVALUELENGTH = TextUtil.getIntegerProperty( properties, PROP_CUSTOMPROP_MAXVALUELENGTH, DEFAULT_MAX_PROPVALUELENGTH );

        log.info( "Wikipages are read from '" + m_pageDirectory + "'" );
    }


    String getPageDirectory()
    {
        return m_pageDirectory;
    }

    private static final String[] WINDOWS_DEVICE_NAMES = {
        "con", "prn", "nul", "aux", "lpt1", "lpt2", "lpt3", "lpt4", "lpt5", "lpt6", "lpt7", "lpt8", "lpt9",
        "com1", "com2", "com3", "com4", "com5", "com6", "com7", "com8", "com9"
    };

    /**
     *  This makes sure that the queried page name is still readable by the file system.  For example, all XML entities
     *  and slashes are encoded with the percent notation.
     *
     *  @param pagename The name to mangle
     *  @return The mangled name.
     */
    protected String mangleName( String pagename ) {
        pagename = TextUtil.urlEncode( pagename, m_encoding );
        pagename = TextUtil.replaceString( pagename, "/", "%2F" );

        //  Names which start with a dot must be escaped to prevent problems. Since we use URL encoding, this is invisible in our unescaping.
        if( pagename.startsWith( "." ) ) {
            pagename = "%2E" + pagename.substring( 1 );
        }

        if( m_windowsHackNeeded ) {
            final String pn = pagename.toLowerCase();
            for( final String windowsDeviceName : WINDOWS_DEVICE_NAMES ) {
                if( windowsDeviceName.equals( pn ) ) {
                    pagename = "$$$" + pagename;
                }
            }
        }

        return pagename;
    }

    /**
     *  This makes the reverse of mangleName.
     *
     *  @param filename The filename to unmangle
     *  @return The unmangled name.
     */
    protected String unmangleName( String filename ) {
        // The exception should never happen.
        if( m_windowsHackNeeded && filename.startsWith( "$$$" ) && filename.length() > 3 ) {
            filename = filename.substring( 3 );
        }

        return TextUtil.urlDecode( filename, m_encoding );
    }

    /**
     *  Finds a Wiki page from the page repository.
     *
     *  @param page The name of the page.
     *  @return A File to the page.  May be null.
     */
    protected File findPage( final String page ) {
        return new File( m_pageDirectory, mangleName( page ) + FILE_EXT );
    }

    /**
     *  {@inheritDoc}
     */
    @Override
    public boolean pageExists( final String page ) {
        return findPage( page ).exists();
    }

    /**
     *  {@inheritDoc}
     */
    @Override
    public boolean pageExists( final String page, final int version ) {
        return pageExists( page );
    }

    /**
     *  This implementation just returns the current version, as filesystem does not provide versioning information for now.
     *
     *  {@inheritDoc}
     */
    @Override
    public String getPageText( final String page, final int version ) throws ProviderException {
        return getPageText( page );
    }

    /**
     *  Read the text directly from the correct file.
     */
    private String getPageText( final String page ) {
        String result  = null;
        final File pagedata = findPage( page );
        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 );
                }
            } else {
                log.warn( "Failed to read page '" + page + "' from '" + pagedata.getAbsolutePath() + "', possibly a permissions problem" );
            }
        } else {
            // This is okay.
            log.info( "New page '" + page + "'" );
        }

        return result;
    }

    /**
     *  {@inheritDoc}
     */
    @Override
    public void putPageText( final Page page, final String text ) throws ProviderException {
        final File file = findPage( page.getName() );
        try( final PrintWriter out = new PrintWriter( new OutputStreamWriter( new FileOutputStream( file ), m_encoding ) ) ) {
            out.print( text );
        } catch( final IOException e ) {
            log.error( "Saving failed", e );
        }
    }

    /**
     *  {@inheritDoc}
     */
    @Override
    public Collection< Page > getAllPages()  throws ProviderException {
        log.debug("Getting all pages...");
        final ArrayList< Page > set = new ArrayList<>();
        final File wikipagedir = new File( m_pageDirectory );
        final File[] wikipages = wikipagedir.listFiles( new WikiFileFilter() );

        if( wikipages == null ) {
            log.error("Wikipages directory '" + m_pageDirectory + "' does not exist! Please check " + PROP_PAGEDIR + " in jspwiki.properties.");
            throw new ProviderException( "Page directory does not exist" );
        }

        for( final File wikipage : wikipages ) {
            final String wikiname = wikipage.getName();
            final int cutpoint = wikiname.lastIndexOf( FILE_EXT );
            final Page page = getPageInfo( unmangleName( wikiname.substring( 0, cutpoint ) ), PageProvider.LATEST_VERSION );
            if( page == null ) {
                // This should not really happen.
                // FIXME: Should we throw an exception here?
                log.error( "Page " + wikiname + " was found in directory listing, but could not be located individually." );
                continue;
            }

            set.add( page );
        }

        return set;
    }

    /**
     *  Does not work.
     *
     *  @param date {@inheritDoc}
     *  @return {@inheritDoc}
     */
    @Override
    public Collection< Page > getAllChangedSince( final Date date )
    {
        return new ArrayList<>(); // FIXME
    }

    /**
     *  {@inheritDoc}
     */
    @Override
    public int getPageCount() {
        final File wikipagedir = new File( m_pageDirectory );
        final File[] wikipages = wikipagedir.listFiles( new WikiFileFilter() );
        return wikipages != null ? wikipages.length : 0;
    }

    /**
     * Iterates through all WikiPages, matches them against the given query, and returns a Collection of SearchResult objects.
     *
     * {@inheritDoc}
     */
    @Override
    public Collection< SearchResult > findPages( final QueryItem[] query ) {
        final File wikipagedir = new File( m_pageDirectory );
        final TreeSet< SearchResult > res = new TreeSet<>( new SearchResultComparator() );
        final SearchMatcher matcher = new SearchMatcher( m_engine, query );
        final File[] wikipages = wikipagedir.listFiles( new WikiFileFilter() );

        if( wikipages != null ) {
            for( final File wikipage : wikipages ) {
                final String filename = wikipage.getName();
                final int cutpoint = filename.lastIndexOf( FILE_EXT );
                final String wikiname = unmangleName( filename.substring( 0, cutpoint ) );
                try( final FileInputStream input = new FileInputStream( wikipage ) ) {
                    final String pagetext = FileUtil.readContents( input, m_encoding );
                    final SearchResult comparison = matcher.matchPageContent( wikiname, pagetext );
                    if( comparison != null ) {
                        res.add( comparison );
                    }
                } catch( final IOException e ) {
                    log.error( "Failed to read " + filename, e );
                }
            }
        }

        return res;
    }

    /**
     *  Always returns the latest version, since FileSystemProvider
     *  does not support versioning.
     *
     *  {@inheritDoc}
     */
    @Override
    public WikiPage getPageInfo( final String page, final int version ) throws ProviderException {
        final File file = findPage( page );
        if( !file.exists() ) {
            return null;
        }

        final WikiPage p = new WikiPage( m_engine, page );
        p.setLastModified( new Date( file.lastModified() ) );

        return p;
    }

    /**
     *  The FileSystemProvider provides only one version.
     *
     *  {@inheritDoc}
     */
    @Override
    public List< Page > getVersionHistory( final String page ) throws ProviderException {
        final ArrayList< Page > list = new ArrayList<>();
        list.add( getPageInfo( page, PageProvider.LATEST_VERSION ) );

        return list;
    }

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

    /**
     *  {@inheritDoc}
     */
    @Override
    public void deleteVersion( final String pageName, final int version ) throws ProviderException {
        if( version == WikiProvider.LATEST_VERSION ) {
            final File f = findPage( pageName );
            f.delete();
        }
    }

    /**
     *  {@inheritDoc}
     */
    @Override
    public void deletePage( final String pageName ) throws ProviderException {
        final File f = findPage( pageName );
        f.delete();
    }

    /**
     * Set the custom properties provided into the given page.
     *
     * @since 2.10.2
     */
    protected void setCustomProperties( final Page page, final Properties properties ) {
        final Enumeration< ? > propertyNames = properties.propertyNames();
    	while( propertyNames.hasMoreElements() ) {
            final String key = ( String )propertyNames.nextElement();
            if( !key.equals( Page.AUTHOR ) && !key.equals( Page.CHANGENOTE ) && !key.equals( Page.VIEWCOUNT ) ) {
                page.setAttribute( key, properties.get( key ) );
            }
    	}
    }

    /**
     * Get custom properties using {@link #addCustomProperties(Page, Properties)}, validate them using {@link #validateCustomPageProperties(Properties)}
     * and add them to default properties provided
     *
     * @since 2.10.2
     */
    protected void getCustomProperties( final Page page, final Properties defaultProperties ) throws IOException {
        final Properties customPageProperties = addCustomProperties( page, defaultProperties );
        validateCustomPageProperties( customPageProperties );
        defaultProperties.putAll( customPageProperties );
    }

    /**
     * By default all page attributes that start with "@" are returned as custom properties.
     * This can be overwritten by custom FileSystemProviders to save additional properties.
     * CustomPageProperties are validated by {@link #validateCustomPageProperties(Properties)}
     *
     * @since 2.10.2
     * @param page the current page
     * @param props the default properties of this page
     * @return default implementation returns empty Properties.
     */
    protected Properties addCustomProperties( final Page page, final Properties props ) {
        final Properties customProperties = new Properties();
        if( page != null ) {
            final Map< String, Object > atts = page.getAttributes();
            for( final String key : atts.keySet() ) {
                final Object value = atts.get( key );
                if( key.startsWith( "@" ) && value != null ) {
                    customProperties.put( key, value.toString() );
                }
            }

        }
        return customProperties;
    }

    /**
     * Default validation, validates that key and value is ASCII <code>StringUtils.isAsciiPrintable()</code> and within lengths set up in jspwiki-custom.properties.
     * This can be overwritten by custom FileSystemProviders to validate additional properties
     * See https://issues.apache.org/jira/browse/JSPWIKI-856
     * @since 2.10.2
     * @param customProperties the custom page properties being added
     */
    protected void validateCustomPageProperties( final Properties customProperties ) throws IOException {
    	// Default validation rules
        if( customProperties != null && !customProperties.isEmpty() ) {
            if( customProperties.size() > MAX_PROPLIMIT ) {
                throw new IOException( "Too many custom properties. You are adding " + customProperties.size() + ", but max limit is " + MAX_PROPLIMIT );
            }
            final Enumeration< ? > propertyNames = customProperties.propertyNames();
            while( propertyNames.hasMoreElements() ) {
                final String key = ( String )propertyNames.nextElement();
                final String value = ( String )customProperties.get( key );
                if( key != null ) {
                    if( key.length() > MAX_PROPKEYLENGTH ) {
                        throw new IOException( "Custom property key " + key + " is too long. Max allowed length is " + MAX_PROPKEYLENGTH );
                    }
                    if( !StringUtils.isAsciiPrintable( key ) ) {
                        throw new IOException( "Custom property key " + key + " is not simple ASCII!" );
                    }
                }
                if( value != null ) {
                    if( value.length() > MAX_PROPVALUELENGTH ) {
                        throw new IOException( "Custom property key " + key + " has value that is too long. Value=" + value + ". Max allowed length is " + MAX_PROPVALUELENGTH );
                    }
                    if( !StringUtils.isAsciiPrintable( value ) ) {
                        throw new IOException( "Custom property key " + key + " has value that is not simple ASCII! Value=" + value );
                    }
                }
            }
        }
    }

    /**
     *  A simple filter which filters only those filenames which correspond to the
     *  file extension used.
     */
    public static class WikiFileFilter implements FilenameFilter {
        /**
         *  {@inheritDoc}
         */
        @Override
        public boolean accept( final File dir, final String name ) {
            return name.endsWith( FILE_EXT );
        }
    }

}
