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

import org.apache.log4j.Logger;
import org.apache.oro.text.regex.Pattern;
import org.apache.oro.text.regex.Perl5Matcher;
import org.apache.wiki.api.core.Context;
import org.apache.wiki.api.exceptions.ProviderException;

import java.util.Arrays;
import java.util.Comparator;
import java.util.List;


/**
 * Link parsing operations.
 *
 * @since 2.10.3
 */
public class LinkParsingOperations {

    private static final Logger log = Logger.getLogger( LinkParsingOperations.class );
    private final Context wikiContext;

    /**
     *  This list contains all IANA registered URI protocol types as of September 2004 + a few well-known extra types.
     *
     *  JSPWiki recognises all of them as external links.
     *
     *  This array is sorted during class load, so you can just dump here whatever you want in whatever order you want.
     */
    static final String[] EXTERNAL_LINKS = {
        "http:", "ftp:", "https:", "mailto:",
        "news:", "file:", "rtsp:", "mms:", "ldap:",
        "gopher:", "nntp:", "telnet:", "wais:",
        "prospero:", "z39.50s", "z39.50r", "vemmi:",
        "imap:", "nfs:", "acap:", "tip:", "pop:",
        "dav:", "opaquelocktoken:", "sip:", "sips:",
        "tel:", "fax:", "modem:", "soap.beep:", "soap.beeps",
        "xmlrpc.beep", "xmlrpc.beeps", "urn:", "go:",
        "h323:", "ipp:", "tftp:", "mupdate:", "pres:",
        "im:", "mtqp", "smb:"
    };

    static {
        Arrays.sort( EXTERNAL_LINKS );
    }

    public LinkParsingOperations( final Context wikiContext ) {
    	this.wikiContext = wikiContext;
    }

    /**
     *  Returns true, if the link in question is an access rule.
     *
     * @param link The link text
     * @return {@code true}, if this represents an access rule.
     */
    public boolean isAccessRule( final String link ) {
        return link.startsWith("{ALLOW") || link.startsWith("{DENY");
    }

    /**
     *  Returns true if the link is really command to insert a plugin.
     *  <P>
     *  Currently we just check if the link starts with "{INSERT", or just plain "{" but not "{$".
     *
     *  @param link Link text, i.e. the contents of text between [].
     *  @return True, if this link seems to be a command to insert a plugin here.
     */
    public boolean isPluginLink( final String link ) {
        return link.startsWith( "{INSERT" ) ||
               ( link.startsWith( "{" ) && !link.startsWith( "{$" ) );
    }

    /**
     * Returns true if the link is a metadata link.
     *
     * @param link The link text
     * @return {@code true}, if this represents a metadata link.
     */
    public boolean isMetadata( final String link ) {
        return link.startsWith( "{SET" );
    }

    /**
     * Returns true if the link is really command to insert a variable.
     * <P>
     * Currently we just check if the link starts with "{$".
     *
     * @param link The link text
     * @return {@code true}, if this represents a variable link.
     */
    public boolean isVariableLink( final String link ) {
        return link.startsWith( "{$" );
    }

    /**
     * Returns true, if this Link represents an InterWiki link (of the form wiki:page).
     *
     * @return {@code true}, if this Link represents an InterWiki link, {@code false} otherwise.
     */
    public boolean isInterWikiLink( final String page ) {
        return interWikiLinkAt( page ) != -1;
    }

    /**
     * Returns true, if this Link represents an InterWiki link (of the form wiki:page).
     *
     * @return {@code true}, if this Link represents an InterWiki link, {@code false} otherwise.
     */
    public int interWikiLinkAt( final String page ) {
        return page.indexOf( ':' );
    }

    /**
     * Figures out if a link is an off-site link.  This recognizes the most common protocols by checking how it starts.
     *
     * @param page The link to check.
     * @return true, if this is a link outside of this wiki.
     */
    public boolean isExternalLink( final String page ) {
        final int idx = Arrays.binarySearch( EXTERNAL_LINKS, page, new StartingComparator() );

        // We need to check here once again; otherwise we might get a match for something like "h".
        return idx >= 0 && page.startsWith( EXTERNAL_LINKS[ idx ] );
    }

    /**
     *  Matches the given link to the list of image name patterns to determine whether it should be treated as an inline image or not.
     */
    public boolean isImageLink( String link, final boolean isImageInlining, final List< Pattern > inlineImagePatterns ) {
        if( isImageInlining ) {
            link = link.toLowerCase();
            for( final Pattern p : inlineImagePatterns ) {
                if( new Perl5Matcher().matches( link, p ) ) {
                    return true;
                }
            }
        }

        return false;
    }

    /**
     * Returns {@code true}, if the link name exists; otherwise it returns {@code false}.
     *
     * @param page link name
     * @return {@code true}, if the link name exists; otherwise it returns {@code false}.
     */
    public boolean linkExists( final String page ) {
        if( page == null || page.length() == 0 ) {
            return false;
        }
        try {
            return wikiContext.getEngine().getFinalPageName( page ) != null;
        } catch( final ProviderException e ) {
            log.warn( "TranslatorReader got a faulty page name [" + page + "]!", e );
            return false;
        }
    }

    /**
     * Returns link name, if it exists; otherwise it returns {@code null}.
     *
     * @param page link name
     * @return link name, if it exists; otherwise it returns {@code null}.
     */
    public String linkIfExists( final String page ) {
        if( page == null || page.length() == 0 ) {
            return null;
        }
        try {
            return wikiContext.getEngine().getFinalPageName( page );
        } catch( final ProviderException e ) {
            log.warn( "TranslatorReader got a faulty page name [" + page + "]!", e );
            return null;
        }
    }

    /**
     * Compares two Strings, and if one starts with the other, then returns 0. Otherwise just like the normal Comparator for strings.
     */
    private static class StartingComparator implements Comparator< String > {

        /**
         * {@inheritDoc}
         *
         * @see Comparator#compare(Object, Object)
         */
        @Override
        public int compare( final String s1, final String s2 ) {
            if( s1.length() > s2.length() ) {
                if( s1.startsWith( s2 ) && s2.length() > 1 ) {
                    return 0;
                }
            } else if( s2.startsWith( s1 ) && s1.length() > 1 ) {
                return 0;
            }

            return s1.compareTo( s2 );
        }

    }

}
