/*
    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 Page getPageInfo( final String page, final int version ) throws ProviderException {
        final File file = findPage( page );
        if( !file.exists() ) {
            return null;
        }

        final Page 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 );
        }
    }

}
