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

import org.apache.log4j.Logger;
import org.apache.wiki.InternalWikiException;
import org.apache.wiki.WikiContext;
import org.apache.wiki.WikiEngine;
import org.apache.wiki.WikiPage;
import org.apache.wiki.api.exceptions.ProviderException;
import org.apache.wiki.api.exceptions.WikiException;
import org.apache.wiki.attachment.Attachment;
import org.apache.wiki.event.WikiEventManager;
import org.apache.wiki.event.WikiPageRenameEvent;
import org.apache.wiki.parser.JSPWikiMarkupParser;
import org.apache.wiki.parser.MarkupParser;
import org.apache.wiki.util.TextUtil;

import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Provides page renaming functionality. Note that there used to be a similarly named class in 2.6, but due to unclear copyright, the
 * class was completely rewritten from scratch for 2.8.
 *
 * @since 2.8
 */
public class PageRenamer {

    private static final Logger log = Logger.getLogger( PageRenamer.class );
    
    private boolean m_camelCase = false;
    
    /**
     *  Renames a page.
     *  
     *  @param context The current context.
     *  @param renameFrom The name from which to rename.
     *  @param renameTo The new name.
     *  @param changeReferrers If true, also changes all the referrers.
     *  @return The final new name (in case it had to be modified)
     *  @throws WikiException If the page cannot be renamed.
     */
    public String renamePage( final WikiContext context, final String renameFrom, final String renameTo, final boolean changeReferrers ) throws WikiException {
        //  Sanity checks first
        if( renameFrom == null || renameFrom.length() == 0 ) {
            throw new WikiException( "From name may not be null or empty" );
        }
        if( renameTo == null || renameTo.length() == 0 ) {
            throw new WikiException( "To name may not be null or empty" );
        }
       
        //  Clean up the "to" -name so that it does not contain anything illegal
        final String renameToClean = MarkupParser.cleanLink( renameTo.trim() );
        if( renameToClean.equals( renameFrom ) ) {
            throw new WikiException( "You cannot rename the page to itself" );
        }
        
        //  Preconditions: "from" page must exist, and "to" page must not yet exist.
        final WikiEngine engine = context.getEngine();
        final WikiPage fromPage = engine.getPage( renameFrom );
        if( fromPage == null ) {
            throw new WikiException("No such page "+renameFrom);
        }
        WikiPage toPage = engine.getPage( renameToClean );
        if( toPage != null ) {
            throw new WikiException( "Page already exists " + renameToClean );
        }
        
        final Set< String > referrers = getReferencesToChange( fromPage, engine );

        //  Do the actual rename by changing from the frompage to the topage, including all of the attachments
        //  Remove references to attachments under old name
        final List< Attachment > attachmentsOldName = engine.getAttachmentManager().listAttachments( fromPage );
        for( final Attachment att: attachmentsOldName ) {
            final WikiPage fromAttPage = engine.getPage( att.getName() );
            engine.getReferenceManager().pageRemoved( fromAttPage );
        }

        engine.getPageManager().getProvider().movePage( renameFrom, renameToClean );
        if( engine.getAttachmentManager().attachmentsEnabled() ) {
            engine.getAttachmentManager().getCurrentProvider().moveAttachmentsForPage( renameFrom, renameToClean );
        }
        
        //  Add a comment to the page notifying what changed.  This adds a new revision to the repo with no actual change.
        toPage = engine.getPage( renameToClean );
        if( toPage == null ) {
            throw new InternalWikiException( "Rename seems to have failed for some strange reason - please check logs!" );
        }
        toPage.setAttribute( WikiPage.CHANGENOTE, fromPage.getName() + " ==> " + toPage.getName() );
        toPage.setAuthor( context.getCurrentUser().getName() );
        engine.getPageManager().putPageText( toPage, engine.getPureText( toPage ) );

        //  Update the references
        engine.getReferenceManager().pageRemoved( fromPage );
        engine.updateReferences( toPage );

        //  Update referrers
        if( changeReferrers ) {
            updateReferrers( context, fromPage, toPage, referrers );
        }

        //  re-index the page including its attachments
        engine.getSearchManager().reindexPage( toPage );
        
        final Collection< Attachment > attachmentsNewName = engine.getAttachmentManager().listAttachments( toPage );
        for( final Attachment att:attachmentsNewName ) {
            final WikiPage toAttPage = engine.getPage( att.getName() );
            // add reference to attachment under new page name
            engine.updateReferences( toAttPage );
            engine.getSearchManager().reindexPage( att );
        }

        // Currently not used internally by JSPWiki itself, but you can use it for something else.
        WikiEventManager.fireEvent( this, new WikiPageRenameEvent( this, renameFrom, renameToClean ) );

        //  Done, return the new name.
        return renameToClean;
    }

    /**
     *  This method finds all the pages which have anything to do with the fromPage and
     *  change any referrers it can figure out in that page.
     *  
     *  @param context WikiContext in which we operate
     *  @param fromPage The old page
     *  @param toPage The new page
     */
    private void updateReferrers( final WikiContext context, final WikiPage fromPage, final WikiPage toPage, final Set< String > referrers ) {
        if( referrers.isEmpty() ) { // No referrers
            return;
        }

        final WikiEngine engine = context.getEngine();
        for( String pageName : referrers ) {
            //  In case the page was just changed from under us, let's do this small kludge.
            if( pageName.equals( fromPage.getName() ) ) {
                pageName = toPage.getName();
            }
            
            final WikiPage p = engine.getPage( pageName );

            final String sourceText = engine.getPureText( p );
            String newText = replaceReferrerString( context, sourceText, fromPage.getName(), toPage.getName() );

            m_camelCase = TextUtil.getBooleanProperty( engine.getWikiProperties(), JSPWikiMarkupParser.PROP_CAMELCASELINKS, m_camelCase );
            if( m_camelCase ) {
                newText = replaceCCReferrerString( context, newText, fromPage.getName(), toPage.getName() );
            }
            
            if( !sourceText.equals( newText ) ) {
                p.setAttribute( WikiPage.CHANGENOTE, fromPage.getName()+" ==> "+toPage.getName() );
                p.setAuthor( context.getCurrentUser().getName() );
         
                try {
                    engine.getPageManager().putPageText( p, newText );
                    engine.updateReferences( p );
                } catch( final ProviderException e ) {
                    //  We fail with an error, but we will try to continue to rename other referrers as well.
                    log.error("Unable to perform rename.",e);
                }
            }
        }
    }

    private Set<String> getReferencesToChange( final WikiPage fromPage, final WikiEngine engine ) {
        final Set< String > referrers = new TreeSet<>();
        final Collection< String > r = engine.getReferenceManager().findReferrers( fromPage.getName() );
        if( r != null ) {
            referrers.addAll( r );
        }
        
        try {
            final List< Attachment > attachments = engine.getAttachmentManager().listAttachments( fromPage );
            for( final Attachment att : attachments  ) {
                final Collection< String > c = engine.getReferenceManager().findReferrers( att.getName() );
                if( c != null ) {
                    referrers.addAll( c );
                }
            }
        } catch( final ProviderException e ) {
            // We will continue despite this error
            log.error( "Provider error while fetching attachments for rename", e );
        }
        return referrers;
    }

    /**
     *  Replaces camelcase links.
     */
    private String replaceCCReferrerString( final WikiContext context, final String sourceText, final String from, final String to ) {
        final StringBuilder sb = new StringBuilder( sourceText.length()+32 );
        final Pattern linkPattern = Pattern.compile( "\\p{Lu}+\\p{Ll}+\\p{Lu}+[\\p{L}\\p{Digit}]*" );
        final Matcher matcher = linkPattern.matcher( sourceText );
        int start = 0;
        
        while( matcher.find( start ) ) {
            final String match = matcher.group();
            sb.append( sourceText.substring( start, matcher.start() ) );
            final int lastOpenBrace = sourceText.lastIndexOf( '[', matcher.start() );
            final int lastCloseBrace = sourceText.lastIndexOf( ']', matcher.start() );
            
            if( match.equals( from ) && lastCloseBrace >= lastOpenBrace ) {
                sb.append( to );
            } else {
                sb.append( match );
            }
            
            start = matcher.end();
        }
        
        sb.append( sourceText.substring( start ) );
        
        return sb.toString();
    }

    private String replaceReferrerString( final WikiContext context, final String sourceText, final String from, final String to ) {
        final StringBuilder sb = new StringBuilder( sourceText.length()+32 );
        
        // This monstrosity just looks for a JSPWiki link pattern.  But it is pretty cool for a regexp, isn't it?  If you can
        // understand this in a single reading, you have way too much time in your hands.
        final Pattern linkPattern = Pattern.compile( "([\\[\\~]?)\\[([^\\|\\]]*)(\\|)?([^\\|\\]]*)(\\|)?([^\\|\\]]*)\\]" );
        final Matcher matcher = linkPattern.matcher( sourceText );
        int start = 0;
        
        while( matcher.find( start ) ) {
            char charBefore = (char)-1;
            
            if( matcher.start() > 0 ) {
                charBefore = sourceText.charAt( matcher.start() - 1 );
            }
            
            if( matcher.group(1).length() > 0 || charBefore == '~' || charBefore == '[' ) {
                //  Found an escape character, so I am escaping.
                sb.append( sourceText.substring( start, matcher.end() ) );
                start = matcher.end();
                continue;
            }

            String text = matcher.group(2);
            String link = matcher.group(4);
            final String attr = matcher.group(6);
             
            if( link.length() == 0 ) {
                text = replaceSingleLink( context, text, from, to );
            } else {
                link = replaceSingleLink( context, link, from, to );
                
                //  A very simple substitution, but should work for quite a few cases.
                text = TextUtil.replaceString( text, from, to );
            }
        
            //
            //  Construct the new string
            //
            sb.append( sourceText.substring( start, matcher.start() ) );
            sb.append( "[" ).append( text );
            if( link.length() > 0 ) {
                sb.append( "|" ).append( link );
            }
            if( attr.length() > 0 ) {
                sb.append( "|" ).append( attr );
            }
            sb.append( "]" );
            
            start = matcher.end();
        }
        
        sb.append( sourceText.substring( start ) );
        
        return sb.toString();
    }

    /**
     *  This method does a correct replacement of a single link, taking into account anchors and attachments.
     */
    private String replaceSingleLink( final WikiContext context, final String original, final String from, final String newlink ) {
        final int hash = original.indexOf( '#' );
        final int slash = original.indexOf( '/' );
        String realLink = original;

        if( hash != -1 ) {
            realLink = original.substring( 0, hash );
        }
        if( slash != -1 ) {
            realLink = original.substring( 0,slash );
        }

        realLink = MarkupParser.cleanLink( realLink );
        final String oldStyleRealLink = MarkupParser.wikifyLink( realLink );
        
        //WikiPage realPage  = context.getEngine().getPage( reallink );
        // WikiPage p2 = context.getEngine().getPage( from );
        
        // System.out.println("   "+reallink+" :: "+ from);
        // System.out.println("   "+p+" :: "+p2);
        
        //
        //  Yes, these point to the same page.
        //
        if( realLink.equals( from ) || original.equals( from ) || oldStyleRealLink.equals( from ) ) {
            //
            //  if the original contains blanks, then we should introduce a link, for example:  [My Page]  =>  [My Page|My Renamed Page]
            final int blank = realLink.indexOf( " ");
            
            if( blank != -1 ) {
                return original + "|" + newlink;
            }
            
            return newlink +
                   ( ( hash > 0 ) ? original.substring( hash ) : "" ) +
                   ( ( slash > 0 ) ? original.substring( slash ) : "" ) ;
        }
        
        return original;
    }
}
