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

import org.apache.wiki.WikiContext;
import org.apache.wiki.api.core.Context;
import org.apache.wiki.api.exceptions.PluginException;
import org.apache.wiki.api.plugin.Plugin;
import org.apache.wiki.plugin.DefaultPluginManager;
import org.apache.wiki.plugin.PluginManager;
import org.apache.wiki.preferences.Preferences;
import org.apache.wiki.util.FormUtil;

import java.text.MessageFormat;
import java.util.Map;
import java.util.ResourceBundle;

/**
 */
public class FormOutput extends FormElement {
    /**
     * Executes the FormHandler specified in a Form 'output' plugin,
     * using entries provided in the HttpRequest as FormHandler
     * parameters.
     * <p>
     * If the parameter 'populate' was given, the WikiPlugin it names
     * is used to get default values. (It probably makes a lot of
     * sense for this to be the same plugin as the handler.) 
     * Information for the populator can be given with the FormSet
     * plugin. If 'populate' is not specified, the form is not
     * displayed.
     * <p>
     * Should there be no HTTP request associated with this request,
     * the method will return immediately with an empty string.
     * 
     * @param ctx {@inheritDoc}
     * @param params {@inheritDoc}
     * @return {@inheritDoc}
     */
    @Override
    public String execute( final Context ctx, final Map< String, String > params ) throws PluginException {
        //  If there is no HTTP request, returns immediately.
        if( ctx.getHttpRequest() == null ) {
            return "";
        }
        final ResourceBundle rb = Preferences.getBundle( ctx, Plugin.CORE_PLUGINS_RESOURCEBUNDLE );
        
        // If we are NOT here due to this form being submitted, we do nothing.
        // The submitted form MUST have parameter 'formname' equal to the name
        // parameter of this Form plugin.

        final String formName   = params.get( PARAM_FORM );
        final String submitForm = ctx.getHttpParameter( PARAM_FORMNAMEHIDDEN );
        final String populator  = params.get( PARAM_POPULATE );

        if( formName == null || !formName.equals( submitForm ) ) {
            // No submitForm -> this was not a submission from the
            // generated form.  If populate is specified, we'll go
            // ahead and let the handler (populator) put stuff into
            // the context, otherwise we'll just hide.
            if( !PARAM_HANDLER.equals( populator ) )
                return "";
            // If population was allowed, we should first  
        }

        final String handler = params.get( PARAM_HANDLER );
        if( handler == null || handler.length() == 0 ) {
            // Need to print out an error here as this form is misconfigured
            return "<p class=\"error\">" + MessageFormat.format( rb.getString( "formoutput.missingargument" ), PARAM_HANDLER ) + "</p>";
        }

        final String sourcePage = ctx.getPage().getName();
        final String submitServlet = ctx.getURL( WikiContext.VIEW, sourcePage );

        // If there is previous FormInfo available - say, from a
        // FormSet plugin - use it.
        FormInfo info = getFormInfo( ctx );
        if( info == null ) {
            // Reconstruct the form info from post data
            info = new FormInfo();
            info.setName( formName );
        }
        // Force override of handler and submit.
        info.setHandler( handler );
        info.setAction( submitServlet );

        // Sift out all extra parameters, leaving only those submitted in the HTML FORM.
        final Map< String, String > handlerParams = FormUtil.requestToMap( ctx.getHttpRequest(), HANDLERPARAM_PREFIX );
        // Previous submission info may be available from FormSet
        // plugin - add, don't replace.
        info.addSubmission( handlerParams );

        // Pass the _body parameter from FormOutput on to the handler
        info.getSubmission().put( DefaultPluginManager.PARAM_BODY, params.get(DefaultPluginManager.PARAM_BODY ) );

        String handlerOutput = null;
        String error = null;
        try {
            // The plugin _can_ modify the parameters, so we make sure they stay with us.
            final PluginManager pm = ctx.getEngine().getManager( PluginManager.class );
            handlerOutput = pm.execute( ctx, handler, info.getSubmission() );
            info.setResult( handlerOutput );
            info.setStatus( FormInfo.EXECUTED );
        } catch( final PluginException pe ) {
            error = "<p class=\"error\">" + pe.getMessage() + "</p>";
            info.setError( error );
            info.setStatus( FormInfo.ERROR );
        }

        // We store the forminfo, so following Form plugin invocations on this
        // page can decide what to do based on its values.
        storeFormInfo( ctx, info );

        if( error != null )
            return error;

        return handlerOutput != null ? handlerOutput : "";
    }

}
