package com.ecyrd.jspwiki.action;

import java.lang.reflect.Method;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.jsp.PageContext;

import net.sourceforge.stripes.action.RedirectResolution;
import net.sourceforge.stripes.mock.MockHttpServletRequest;
import net.sourceforge.stripes.mock.MockHttpServletResponse;
import net.sourceforge.stripes.mock.MockHttpSession;
import net.sourceforge.stripes.util.ResolverUtil;

import org.apache.jspwiki.api.WikiException;
import org.apache.jspwiki.api.WikiPage;

import com.ecyrd.jspwiki.*;
import com.ecyrd.jspwiki.auth.SessionMonitor;
import com.ecyrd.jspwiki.content.ContentManager;
import com.ecyrd.jspwiki.content.WikiName;
import com.ecyrd.jspwiki.log.Logger;
import com.ecyrd.jspwiki.log.LoggerFactory;
import com.ecyrd.jspwiki.parser.MarkupParser;
import com.ecyrd.jspwiki.providers.ProviderException;
import com.ecyrd.jspwiki.tags.WikiTagBase;
import com.ecyrd.jspwiki.ui.stripes.HandlerInfo;
import com.ecyrd.jspwiki.ui.stripes.WikiActionBeanContext;
import com.ecyrd.jspwiki.url.StripesURLConstructor;
import com.ecyrd.jspwiki.util.TextUtil;

/**
 * <p>
 * Class that looks up {@link WikiActionBean}s, and resolves special pages and
 * JSPs on behalf of a WikiEngine. WikiActionBeanResolver will automatically
 * resolve page names with singular/plural variants. It can also detect the
 * correct WikiActionBean based on parameters supplied in an HTTP request, or
 * due to the JSP being accessed.
 * </p>
 * 
 * @author Andrew Jaquith
 * @since 2.4.22
 */
public final class WikiContextFactory
{
    /**
     * The PageContext attribute name of the WikiEngine stored by
     * WikiInterceptor.
     */
    public static final String ATTR_WIKIENGINE = "wikiEngine";

    /**
     * The PageContext attribute name of the WikiSession stored by
     * WikiInterceptor.
     */
    public static final String ATTR_WIKISESSION = "wikiSession";

    /** Default list of packages to search for WikiActionBean implementations. */
    public static final String DEFAULT_ACTIONBEAN_PACKAGES = "com.ecyrd.jspwiki.action";

    /**
     * Property in jspwiki.properties that specifies packages to search for
     * WikiActionBean implementations.
     */
    public static final String PROPS_ACTIONBEAN_PACKAGES = "jspwiki.actionBean.packages";

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

    private static final long serialVersionUID = 1L;

    /** Prefix in jspwiki.properties signifying special page keys. */
    private static final String PROP_SPECIALPAGE = "jspwiki.specialPage.";

    /**
     * This method can be used to find the WikiContext programmatically from a
     * JSP PageContext. We check the request context. The wiki context, if it
     * exists, is looked up using the key
     * {@link com.ecyrd.jspwiki.tags.WikiTagBase#ATTR_CONTEXT}.
     * 
     * @since 2.4
     * @param pageContext the JSP page context
     * @return Current WikiContext, or null, of no context exists.
     */
    public static WikiContext findContext( PageContext pageContext )
    {
        HttpServletRequest request = (HttpServletRequest) pageContext.getRequest();
        WikiContext context = (WikiContext) request.getAttribute( WikiTagBase.ATTR_CONTEXT );
        return context;
    }

    /**
     * <p>
     * Saves the supplied WikiContext, and the related WikiEngine and
     * WikiSession, in request scope. The WikiContext is saved as an attribute
     * named {@link com.ecyrd.jspwiki.tags.WikiTagBase#ATTR_CONTEXT}. The
     * WikiEngine is also saved as {@link #ATTR_WIKIENGINE}, and the
     * WikiSession as {@link #ATTR_WIKISESSION}. Among other things, by saving
     * these items as attributes, they can be accessed via JSP Expression
     * Language variables, for example <code>${wikiContext}</code>.
     * </p>
     * <p>
     * Note: when the WikiContext is saved, it will be guaranteed to have a
     * non-null WikiPage. If the context as supplied has a WikiPage that is
     * <code>null</code>, the
     * {@link com.ecyrd.jspwiki.WikiEngine#getFrontPage()} will be consulted,
     * and that page will be used.
     * </p>
     * 
     * @param request the HTTP request
     * @param context the WikiContext to save
     * @throws WikiException 
     */
    public static void saveContext( HttpServletRequest request, WikiContext context ) throws WikiException
    {
        // Stash WikiEngine as a request attribute (can be
        // used later as ${wikiEngine} in EL markup)
        WikiEngine engine = context.getEngine();
        request.setAttribute( ATTR_WIKIENGINE, engine );

        // Stash the WikiSession as a request attribute
        WikiSession wikiSession = SessionMonitor.getInstance( engine ).find( request.getSession() );
        request.setAttribute( ATTR_WIKISESSION, wikiSession );

        WikiPage page = context.getPage();
        if( page == null )
        {
            // If the page supplied was blank, default to the front page to
            // avoid NPEs
            page = engine.getFrontPage( ContentManager.DEFAULT_SPACE );
            context.setPage( page );
        }
        request.setAttribute( WikiTagBase.ATTR_CONTEXT, context );
    }

    /** Private map with JSPs as keys, Resolutions as values */
    private final Map<String, RedirectResolution> m_specialRedirects;

    private final WikiEngine m_engine;

    private String m_mockContextPath;

    /** If true, we'll also consider english plurals (+s) a match. */
    private boolean m_matchEnglishPlurals;

    /** Maps (pre-3.0) request contexts map to WikiActionBeans. */
    private final Map<String, HandlerInfo> m_contextMap = new HashMap<String, HandlerInfo>();

    /**
     * Constructs a WikiActionBeanResolver for a given WikiEngine. This
     * constructor will extract the special page references for this wiki and
     * store them in a cache used for resolution.
     * 
     * @param engine the wiki engine
     * @param properties the properties used to initialize the wiki
     */
    public WikiContextFactory( WikiEngine engine, Properties properties )
    {
        super();
        m_engine = engine;
        m_specialRedirects = new HashMap<String, RedirectResolution>();

        initRequestContextMap( properties );
        initSpecialPageRedirects( properties );

        // Do we match plurals?
        m_matchEnglishPlurals = TextUtil.getBooleanProperty( properties, WikiEngine.PROP_MATCHPLURALS, true );

        // Set the path prefix for constructing synthetic Stripes mock requests;
        // trailing slash is removed.
        m_mockContextPath = StripesURLConstructor.getContextPath( engine );

        // TODO: make packages to search in ActionBeanResolver configurable
        // (currently hard-coded)
    }

    /**
     * Looks up and returns the correct HandlerInfo class corresponding to a
     * supplied wiki context. The supplied context name is matched against the
     * values annotated using
     * {@link com.ecyrd.jspwiki.ui.stripes.WikiRequestContext}. If a match is not
     * found, this method throws an IllegalArgumentException.
     * 
     * @param requestContext the context to look up
     * @return the WikiActionBean event handler info
     */
    public HandlerInfo findEventHandler( String requestContext )
    {
        HandlerInfo handler = m_contextMap.get( requestContext );
        if( handler == null )
        {
            throw new IllegalArgumentException( "No HandlerInfo found for request context '" + requestContext + "'!" );
        }
        return handler;
    }

    /**
     * <p>
     * Returns the correct page name, or <code>null</code>, if no such page
     * can be found. Aliases are considered.
     * </p>
     * <p>
     * In some cases, page names can refer to other pages. For example, when you
     * have matchEnglishPlurals set, then a page name "Foobars" will be
     * transformed into "Foobar", should a page "Foobars" not exist, but the
     * page "Foobar" would. This method gives you the correct page name to refer
     * to.
     * </p>
     * <p>
     * This facility can also be used to rewrite any page name, for example, by
     * using aliases. It can also be used to check the existence of any page.
     * </p>
     * 
     * @since 2.4.20
     * @param page the page name.
     * @return The rewritten page name, or <code>null</code>, if the page
     *         does not exist.
     */
    public final String getFinalPageName( String page ) throws ProviderException
    {
        boolean isThere = simplePageExists( page );
        String finalName = page;

        if( !isThere && m_matchEnglishPlurals )
        {
            if( page.endsWith( "s" ) )
            {
                finalName = page.substring( 0, page.length() - 1 );
            }
            else
            {
                finalName += "s";
            }

            isThere = simplePageExists( finalName );
        }

        if( !isThere )
        {
            finalName = MarkupParser.wikifyLink( page );
            isThere = simplePageExists( finalName );

            if( !isThere && m_matchEnglishPlurals )
            {
                if( finalName.endsWith( "s" ) )
                {
                    finalName = finalName.substring( 0, finalName.length() - 1 );
                }
                else
                {
                    finalName += "s";
                }

                isThere = simplePageExists( finalName );
            }
        }

        return isThere ? finalName : null;
    }

    /**
     * <p>
     * If the page is a special page, this method returns a
     * {@link net.sourceforge.stripes.action.RedirectResolution} for that page;
     * otherwise, it returns <code>null</code>.
     * </p>
     * <p>
     * Special pages are non-existent references to other pages. For example,
     * you could define a special page reference "RecentChanges" which would
     * always be redirected to "RecentChanges.jsp" instead of trying to find a
     * Wiki page called "RecentChanges".
     * </p>
     * TODO: fix this algorithm
     */
    public final RedirectResolution getSpecialPageResolution( String page )
    {
        return m_specialRedirects.get( page );
    }

    /**
     * <p>
     * Creates a WikiActionBeanContext instance, associates an HTTP request and
     * response with it, and sets the correct WikiPage into the context if
     * required. This method will determine what page the user requested by
     * delegating to {@link #extractPageFromParameter(HttpServletRequest)}.
     * </p>
     * <p>
     * This method will <em>always</em>return a {@link WikiActionBeanContext}
     * that is properly instantiated. The supplied request and response objects
     * will be associated with the WikiActionBeanContext. The
     * <code>requestContext</code>is required. If either the
     * <code>request</code> or <code>response</code> parameters are
     * <code>null</code>, appropriate mock objects will be substituted
     * instead.
     * </p>
     * <p>
     * This method performs a similar role to the Stripes
     * {@link net.sourceforge.stripes.controller.ActionBeanContextFactory#getContextInstance(HttpServletRequest, HttpServletResponse)}
     * method, in the sense that it will instantiate an arbitrary
     * ActionBeanContext class. However, although this method will correctly
     * identity the page requested by the user (by inspecting request
     * parameters), it will not do anything special if the page is a "special
     * page."
     * </p>
     * 
     * @param request the HTTP request
     * @param response the HTTP request
     * @param requestContext the request context to use by default
     * @return the new WikiActionBeanContext
     */
    public WikiActionBeanContext newContext( HttpServletRequest request, HttpServletResponse response, String requestContext )
                                                                                                                              throws WikiException
    {
        return createContext( requestContext, request, response, null );
    }

    /**
     * <p>
     * Creates a new WikiActionBeanContext for the given HttpServletRequest,
     * HttpServletResponse and WikiPage, using the {@link WikiContext#VIEW}
     * request context. Similar to method
     * {@link #newContext(HttpServletRequest, HttpServletResponse, String)},
     * this method will <em>always</em>return a {@link WikiActionBeanContext}
     * that is properly instantiated. The supplied request and response objects
     * will be associated with the WikiActionBeanContext. If either the
     * <code>request</code> or <code>response</code> parameters are
     * <code>null</code>, appropriate mock objects will be substituted
     * instead.
     * </p>
     * 
     * @param request The HttpServletRequest that should be associated with this
     *            context. This parameter may be <code>null</code>.
     * @param response The HttpServletResponse that should be associated with
     *            this context. This parameter may be <code>null</code>.
     * @param page The WikiPage. If you want to create a WikiContext for an
     *            older version of a page, you must supply this parameter
     * @return the new WikiActionBeanContext
     */
    public WikiActionBeanContext newViewContext( HttpServletRequest request, HttpServletResponse response, WikiPage page )
    {
        // Create a new "view" WikiActionBeanContext, and swallow any exceptions
        WikiActionBeanContext ctx = null;
        try
        {
            ctx = createContext( WikiContext.VIEW, request, response, page );
            if( ctx == null )
            {
                throw new IllegalStateException( "Could not create new WikiContext of type VIEW! This indicates a bug..." );
            }
        }
        catch( WikiException e )
        {
            e.printStackTrace();
            log.error( e.getMessage() );
        }
        return ctx;
    }

    /**
     *  Provides a clean shortcut to newViewContext(null,null,page).
     * 
     *  @param page The WikiPage object for this page.
     *  @return A new WikiPage.
     */
    public WikiActionBeanContext newViewContext( WikiPage page )
    {
        return newViewContext( null, null, page );
    }
    
    /**
     * Searches a set of named packages for WikiActionBean implementations, and
     * returns any it finds.
     * 
     * @param beanPackages the packages to search on the current classpath,
     *            separated by commas
     * @return the discovered classes
     */
    private Set<Class<? extends WikiActionBean>> findBeanClasses( String[] beanPackages )
    {
        ResolverUtil<WikiActionBean> resolver = new ResolverUtil<WikiActionBean>();
        resolver.findImplementations( WikiActionBean.class, beanPackages );
        return resolver.getClasses();
    }

    /**
     * Initializes the internal map that matches wiki request contexts with
     * HandlerInfo objects.
     * 
     * @param properties
     */
    private void initRequestContextMap( Properties properties )
    {
        // Look up all classes that are WikiActionBeans.
        String beanPackagesProp = properties.getProperty( PROPS_ACTIONBEAN_PACKAGES, DEFAULT_ACTIONBEAN_PACKAGES ).trim();
        String[] beanPackages = beanPackagesProp.split( "," );
        Set<Class<? extends WikiActionBean>> beanClasses = findBeanClasses( beanPackages );

        // Stash the contexts and corresponding classes into a Map.
        for( Class<? extends WikiActionBean> beanClass : beanClasses )
        {
            Map<Method, HandlerInfo> handlerMethods = HandlerInfo.getHandlerInfoCollection( beanClass );
            for( HandlerInfo handler : handlerMethods.values() )
            {
                String requestContext = handler.getRequestContext();
                if( m_contextMap.containsKey( requestContext ) )
                {
                    HandlerInfo duplicateHandler = m_contextMap.get( requestContext );
                    log.error( "Bean class " + beanClass.getCanonicalName() + " contains @WikiRequestContext annotation '"
                               + requestContext + "' that duplicates one already declared for "
                               + duplicateHandler.getActionBeanClass() );
                }
                else
                {
                    m_contextMap.put( requestContext, handler );
                    log.info( "Discovered request context '" + requestContext + "' for WikiActionBean="
                              + beanClass.getCanonicalName() + ",event=" + handler.getEventName() );
                }
            }
        }
    }

    /**
     * Skims through a supplied set of Properties and looks for anything with
     * the "special page" prefix, and creates Stripes
     * {@link net.sourceforge.stripes.action.RedirectResolution} objects for any
     * that are found.
     */
    private void initSpecialPageRedirects( Properties properties )
    {
        for( Map.Entry entry : properties.entrySet() )
        {
            String key = (String) entry.getKey();
            if( key.startsWith( PROP_SPECIALPAGE ) )
            {
                String specialPage = key.substring( PROP_SPECIALPAGE.length() );
                String redirectUrl = (String) entry.getValue();
                if( specialPage != null && redirectUrl != null )
                {
                    specialPage = specialPage.trim();
                    
                    // Parse the special page
                    redirectUrl = redirectUrl.trim();
                    try
                    {
                        URI uri = new URI( redirectUrl );
                        if ( uri.getAuthority() == null )
                        {
                            // No http:// ftp:// or other authority, so it must be relative to webapp /
                            if ( !redirectUrl.startsWith( "/" ) )
                            {
                                redirectUrl = "/" + redirectUrl;
                            }
                        }
                    }
                    catch( URISyntaxException e )
                    {
                        // The user supplied a STRANGE reference
                        log.error( "Strange special page reference: " + redirectUrl );
                    }
                    
                    // Add a new RedirectResolution for the special page
                    RedirectResolution resolution = m_specialRedirects.get( specialPage );
                    if( resolution == null )
                    {
                        resolution = new RedirectResolution( redirectUrl );
                        m_specialRedirects.put( specialPage, resolution );
                    }
                }
            }
        }
    }

    /**
     * Creates and returns a new WikiActionBean based on a supplied class, with
     * an instantiated {@link WikiActionBeanContext}. The
     * WikiActionBeanContext's request and response properties will be set to
     * those supplied by the caller; if not supplied, synthetic instances will
     * be substituted.
     * 
     * @param requestContext the request context to use by default
     * @param request
     * @param response
     * @return the newly instantiated bean
     */
    protected WikiActionBeanContext createContext( String requestContext, HttpServletRequest request, HttpServletResponse response,
                                                   WikiPage page ) throws WikiException
    {
        // Create synthetic request if not supplied
        if( request == null )
        {
            request = new MockHttpServletRequest( m_mockContextPath, "/Wiki.jsp" );
            MockHttpSession session = new MockHttpSession( m_engine.getServletContext() );
            ((MockHttpServletRequest) request).setSession( session );
        }

        // Create synthetic response if not supplied
        if( response == null )
        {
            response = new MockHttpServletResponse();
        }
        // Create the WikiActionBeanContext and set all of its relevant
        // properties
        WikiActionBeanContext context = new WikiActionBeanContext();
        context.setRequest( request );
        context.setResponse( response );
        context.setEngine( m_engine );
        context.setServletContext( m_engine.getServletContext() );
        WikiSession wikiSession = SessionMonitor.getInstance( m_engine ).find( request.getSession() );
        context.setWikiSession( wikiSession );

        // Set the request context (and related event name)
        context.setRequestContext( requestContext );

        // Extract and set the WikiPage
        if( page == null )
        {
            String pageName = extractPageFromParameter( request );

            // For view action, default to front page
            if( pageName == null && WikiContext.VIEW.equals( requestContext ) )
            {
                pageName = m_engine.getFrontPage();
            }

            // Make sure the page is resolved properly (taking into account
            // funny plurals)
            if( pageName != null )
            {
                page = resolvePage( request, pageName );
            }
        }

        if( page != null )
        {
            context.setPage( page );
        }

        return context;
    }

    /**
     * <p>
     * Determines the correct wiki page based on a supplied HTTP request. This
     * method attempts to determine the page requested by a user, taking into
     * account special pages. The resolution algorithm will extract the page
     * name from the URL by looking for the first parameter value returned for
     * the <code>page</code> parameter. If a page name was, in fact, passed in
     * the request, this method the correct name after taking into account
     * potential plural matches.
     * </p>
     * <p>
     * If neither of these methods work, or if the request is <code>null</code>
     * this method returns <code>null</code>
     * </p>.
     * 
     * @param request the HTTP request
     * @return the resolved page name
     */
    protected final String extractPageFromParameter( HttpServletRequest request )
    {
        // Corner case when request == null
        if( request == null )
        {
            return null;
        }

        // Extract the page name from the URL directly
        String[] pages = request.getParameterValues( "page" );
        String page = null;
        if( pages != null && pages.length > 0 )
        {
            page = pages[0];
            try
            {
                // Look for singular/plural variants; if one
                // not found, take the one the user supplied
                String finalPage = getFinalPageName( page );
                if( finalPage != null )
                {
                    page = finalPage;
                }
            }
            catch( ProviderException e )
            {
                // FIXME: Should not ignore!
            }
            return page;
        }

        // Didn't resolve; return null
        return page;
    }

    /**
     * Looks up and returns the correct, versioned WikiPage based on a supplied
     * page name and optional <code>version</code> parameter passed in an HTTP
     * request. If the <code>version</code> parameter does not exist in the
     * request, the latest version is returned.
     * 
     * @param request the HTTP request
     * @param page the name of the page to look up; this page <em>must</em>
     *            exist
     * @return the wiki page
     * @throws WikiException 
     */
    protected final WikiPage resolvePage( HttpServletRequest request, String page ) throws WikiException
    {
        // See if the user included a version parameter
        WikiPage wikipage;
        int version = WikiProvider.LATEST_VERSION;
        String rev = request.getParameter( "version" );

        if( rev != null )
        {
            version = Integer.parseInt( rev );
        }

        wikipage = m_engine.getPage( page, version );

        if( wikipage == null )
        {
            page = MarkupParser.cleanLink( page );
            wikipage = m_engine.createPage( WikiName.valueOf( page ) );
        }
        return wikipage;
    }

    /**
     * Determines whether a "page" exists by examining the list of special pages
     * and querying the page manager.
     * 
     * @param page the page to seek
     * @return <code>true</code> if the page exists, <code>false</code>
     *         otherwise
     */
    protected final boolean simplePageExists( String page ) throws ProviderException
    {
        if( m_specialRedirects.containsKey( page ) )
        {
            return true;
        }
        return m_engine.getPageManager().pageExists( page );
    }

    /**
     *  Creates an "empty" wiki context which is used internally sometimes when
     *  access to the repository is desired outside of a request.  This is
     *  really just shorthand of getting a new VIEW context with an imaginary
     *  page.
     *  
     *  @return A valid WikiContext.
     * @throws WikiException 
     */
    // TODO: Should this be better called "newVirtualContext()" or something?  "Empty" is not
    //       very descriptive.
    public WikiContext newEmptyContext() throws WikiException
    {
        WikiPage page = m_engine.createPage( "__DUMMY__");
        return newViewContext( null, null, page );
    }
}
