/*
 * Copyright 2004 The Apache Software Foundation.
 *
 * Licensed 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.pluto.core;

import java.io.IOException;
import java.util.Map;

import javax.portlet.PortletException;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.apache.pluto.descriptors.portlet.PortletAppDD;
import org.apache.pluto.internal.InternalPortletWindow;
import org.apache.pluto.internal.PortletDescriptorRegistry;
import org.apache.pluto.internal.impl.ActionRequestImpl;
import org.apache.pluto.internal.impl.ActionResponseImpl;
import org.apache.pluto.internal.impl.PortletWindowImpl;
import org.apache.pluto.internal.impl.RenderRequestImpl;
import org.apache.pluto.internal.impl.RenderResponseImpl;
import org.apache.pluto.spi.PortletURLProvider;
import org.apache.pluto.OptionalContainerServices;
import org.apache.pluto.PortletContainer;
import org.apache.pluto.PortletContainerException;
import org.apache.pluto.PortletWindow;
import org.apache.pluto.RequiredContainerServices;

/**
 * Default Pluto Container implementation.
 *
 * @author <a href="mailto:ddewolf@apache.org">David H. DeWolf</a>
 * @author <a href="mailto:zheng@apache.org">ZHENG Zhong</a>
 * @author <a href="mailto:esm@apache.org">Elliot Metsger</a>
 * @version 1.0
 * @since Sep 18, 2004
 */
public class PortletContainerImpl implements PortletContainer {

    /** Internal logger. */
    private static final Log LOG = LogFactory.getLog(PortletContainerImpl.class);
    
    
    // Private Member Variables ------------------------------------------------
    
    /** The portlet container name. */
    private String name = null;
    
    /** The required container services associated with this container. */
    private RequiredContainerServices requiredContainerServices = null;
    
    /** The optional container services associated with this container. */
    private OptionalContainerServices optionalContainerServices = null;
    
    /** The servlet context associated with this container. */
    private ServletContext servletContext = null;

    /** Flag indicating whether or not we've been initialized. */
    private boolean initialized = false;
    
    
    // Constructor -------------------------------------------------------------
    
    /** Default Constructor.  Create a container implementation
     *  whith the given name and given services.
     *
     * @param name  the name of the container.
     * @param requiredServices  the required container services implementation.
     * @param optionalServices  the optional container services implementation.
     */
    public PortletContainerImpl(String name,
                                RequiredContainerServices requiredServices,
                                OptionalContainerServices optionalServices) {
        this.name = name;
        this.requiredContainerServices = requiredServices;
        this.optionalContainerServices = optionalServices;
    }
    
    
    // PortletContainer Impl ---------------------------------------------------
    
    /**
     * Initialize the container for use within the given configuration scope.
     * @param servletContext  the servlet context of the portal webapp.
     */
    public void init(ServletContext servletContext)
    throws PortletContainerException {
    	if (servletContext == null) {
    		throw new PortletContainerException(
    				"Unable to initialize portlet container [" + name + "]: "
    				+ "servlet context is null.");
    	}
        this.servletContext = servletContext;
        this.initialized = true;
        infoWithName("Container initialized successfully.");
    }

    /**
     * Determine whether this container has been initialized or not.
     * @return true if the container has been initialized.
     */
    public boolean isInitialized() {
        return initialized;
    }

    /**
     * Destroy this container.
     */
    public void destroy() {
        this.servletContext = null;
        this.initialized = false;
        infoWithName("Container destroyed.");
    }


    /**
     * Renders the portlet associated with the specified portlet window.
     * @param portletWindow  the portlet window.
     * @param request  the servlet request.
     * @param response  the servlet response.
     * @throws IllegalStateException  if the container is not initialized.
     * @throws PortletException
     * @throws IOException
     * @throws PortletContainerException
     * 
     * @see javax.portlet.Portlet#render(javax.portlet.RenderRequest,javax.portlet.RenderResponse)
     */
    public void doRender(PortletWindow portletWindow,
                         HttpServletRequest request,
                         HttpServletResponse response)
    throws PortletException, IOException, PortletContainerException {
    	
    	ensureInitialized();
    	
        InternalPortletWindow internalPortletWindow =
        		new PortletWindowImpl(servletContext, portletWindow);
        debugWithName("Render request received for portlet: "
        		+ portletWindow.getPortletName());
        
        RenderRequestImpl renderRequest = new RenderRequestImpl(
        		this, internalPortletWindow, request);
        RenderResponseImpl renderResponse = new RenderResponseImpl(
        		this, internalPortletWindow, request, response);

        PortletInvoker invoker = new PortletInvoker(internalPortletWindow);
        invoker.render(renderRequest, renderResponse);
        debugWithName("Portlet rendered for: "
        		+ portletWindow.getPortletName());
    }

    /**
     * Process action for the portlet associated with the given portlet window.
     * @param portletWindow  the portlet window.
     * @param request  the servlet request.
     * @param response  the servlet response.
     * @throws PortletException
     * @throws IOException
     * @throws PortletContainerException
     * 
     * @see javax.portlet.Portlet#processAction(javax.portlet.ActionRequest,javax.portlet.ActionResponse)
     */
    public void doAction(PortletWindow portletWindow,
                         HttpServletRequest request,
                         HttpServletResponse response)
    throws PortletException, IOException, PortletContainerException {
    	
    	ensureInitialized();
    	
        InternalPortletWindow internalPortletWindow =
            	new PortletWindowImpl(servletContext, portletWindow);
    	debugWithName("Action request received for portlet: "
    			+ portletWindow.getPortletName());
    	
        ActionRequestImpl actionRequest = new ActionRequestImpl(
        		this, internalPortletWindow, request);
        ActionResponseImpl actionResponse = new ActionResponseImpl(
        		this, internalPortletWindow, request, response);
        
        PortletInvoker invoker = new PortletInvoker(internalPortletWindow);
        invoker.action(actionRequest, actionResponse);
        debugWithName("Portlet action processed for: "
        		+ portletWindow.getPortletName());
        
        // After processing action, send a redirect URL for rendering.
        String location = actionResponse.getRedirectLocation();

        if (location == null) {
        	
        	// Create portlet URL provider to encode redirect URL.
        	debugWithName("No redirect location specified.");
            PortletURLProvider redirectURL = requiredContainerServices
            		.getPortalCallbackService()
            		.getPortletURLProvider(request, internalPortletWindow);
            
            // Encode portlet mode if it is changed.
            if (actionResponse.getChangedPortletMode() != null) {
                redirectURL.setPortletMode(
                		actionResponse.getChangedPortletMode());
            }
            
            // Encode window state if it is changed.
            if (actionResponse.getChangedWindowState() != null) {
                redirectURL.setWindowState(
                		actionResponse.getChangedWindowState());
            }
            
            // Encode render parameters retrieved from action response.
            Map renderParameters = actionResponse.getRenderParameters();
            redirectURL.clearParameters();
            redirectURL.setParameters(renderParameters);
            
            // Encode redirect URL as a render URL.
            redirectURL.setAction(false);
            
            // Set secure of the redirect URL if necessary.
            if (actionRequest.isSecure()) {
                redirectURL.setSecure();
            }
            
            // Encode the redirect URL to a string.
            location = actionResponse.encodeRedirectURL(redirectURL.toString());
        }

        // Here we intentionally use the original response
        // instead of the wrapped internal response.
        response.sendRedirect(location);
        debugWithName("Redirect URL sent.");
    }

    /**
     * Loads the portlet associated with the specified portlet window.
     * @param portletWindow  the portlet window.
     * @param request  the servlet request.
     * @param response  the servlet response.
     * @throws PortletException
     * @throws IOException
     * @throws PortletContainerException
     */
    public void doLoad(PortletWindow portletWindow,
                       HttpServletRequest request,
                       HttpServletResponse response)
    throws PortletException, IOException, PortletContainerException {
    	
    	ensureInitialized();
    	
        InternalPortletWindow internalPortletWindow =
        		new PortletWindowImpl(servletContext, portletWindow);
        debugWithName("Load request received for portlet: "
        		+ portletWindow.getPortletName());
        
        RenderRequestImpl renderRequest = new RenderRequestImpl(
        		this, internalPortletWindow, request);
        RenderResponseImpl renderResponse = new RenderResponseImpl(
        		this, internalPortletWindow, request, response);
        
        PortletInvoker invoker = new PortletInvoker(internalPortletWindow);
        invoker.load(renderRequest, renderResponse);
        debugWithName("Portlet loaded for: " + portletWindow.getPortletName());
    }

    public String getName() {
        return name;
    }

    public RequiredContainerServices getRequiredContainerServices() {
        return requiredContainerServices;
    }

    /**
     * Retrieve the optional container services used by the container.
     * If no implementation was provided during construction, the default
     * instance will be returned.
     *
     * @return services used by the container.
     */
    public OptionalContainerServices getOptionalContainerServices() {
        return optionalContainerServices;
    }
    
    public PortletAppDD getPortletApplicationDescriptor(String context) 
        throws PortletContainerException {
        
        // make sure the container has initialized
        ensureInitialized();
        
        // sanity check
        if (context == null || context.trim().equals("")) {
            final String msg = "Context was null or the empty string.";
            errorWithName(msg);
            throw new PortletContainerException(msg);
        }
        
        // obtain the context of the portlet
        ServletContext portletCtx = servletContext.getContext(context);
        if (portletCtx == null) {
            final String msg = "Unable to obtain the servlet context for " +
                "portlet context [" + context + "].  Ensure the portlet has " +
                "been deployed and that cross context support is enabled.";
            errorWithName(msg);
            throw new PortletContainerException(msg);
        }
        
        // obtain the portlet application descriptor for the portlet
        // context.
        PortletAppDD portletAppDD = PortletDescriptorRegistry
                                        .getRegistry()
                                        .getPortletAppDD(portletCtx);
        
        // we can't return null
        if (portletAppDD == null) {
            final String msg = "Obtained a null portlet application description for " +
                "portlet context [" + context + "]";
            errorWithName(msg);
            throw new PortletContainerException(msg);
        }
        
        return portletAppDD;        
    }
    
    
    // Private Methods ---------------------------------------------------------
    
    /**
     * Ensures that the portlet container is initialized.
     * @throws IllegalStateException  if the container is not initialized.
     */
    private void ensureInitialized() throws IllegalStateException {
    	if (!isInitialized()) {
    		throw new IllegalStateException(
    				"Portlet container [" + name + "] is not initialized.");
    	}
    }
    
    /**
     * Prints a message at DEBUG level with the container name prefix.
     * @param message  log message.
     */
    private void debugWithName(String message) {
    	if (LOG.isDebugEnabled()) {
    		LOG.debug("Portlet Container [" + name + "]: " + message);
    	}
    }
    
    /**
     * Prints a message at INFO level with the container name prefix.
     * @param message  log message.
     */
    private void infoWithName(String message) {
    	if (LOG.isInfoEnabled()) {
    		LOG.info("Portlet Container [" + name + "]: " + message);
    	}
    }
    
    /**
     * Prints a message at ERROR level with the container name prefix.
     * @param message  log message.
     */
    private void errorWithName(String message) {
        if (LOG.isErrorEnabled()) {
            LOG.info("Portlet Container [" + name + "]: " + message);
        }
    }
    
}

