/*
 * 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.myfaces.test.mock;

import java.util.Locale;
import javax.faces.FactoryFinder;
import javax.faces.application.ApplicationFactory;
import javax.faces.component.UIViewRoot;
import javax.faces.lifecycle.LifecycleFactory;
import javax.faces.render.RenderKitFactory;
import javax.servlet.ServletRequestEvent;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
import org.apache.myfaces.test.config.ResourceBundleVarNames;
import org.apache.myfaces.test.mock.lifecycle.MockLifecycle;
import org.apache.myfaces.test.mock.lifecycle.MockLifecycleFactory;

/**
 *
 */
public class MockedJsfTestContainer implements HttpSessionListener
{

    // ------------------------------------------------------------ Constructors

    /**
     * <p>Construct a new instance of this test case.</p>
     *
     * @param name Name of this test case
     */
    public MockedJsfTestContainer()
    {
    }

    // ---------------------------------------------------- Overall Test Methods

    /**
     * <p>Set up instance variables required by this test case.</p>
     */
    public void setUp()
    {
        // Set up Servlet API Objects
        setUpServletContext();

        // Set up JSF API Objects
        FactoryFinder.releaseFactories();

        setFactories();

        setUpJSFObjects();
    }
    
    /**
     * This method call both setUp() and startRequest().
     */
    public void setUpAll()
    {
        setUp();
        startRequest();
    }
    
    /**
     * This method call both endRequest() and tearDown().
     */
    public void tearDownAll()
    {
        endRequest();
        tearDown();
    }

    /**
     * <p>Setup JSF object used for the test. By default it calls to the following
     * methods in this order:</p>
     * 
     * <ul>
     * <li><code>setUpLifecycle();</code></li>
     * <li><code>setUpApplication();</code></li>
     * <li><code>setUpRenderKit();</code></li>
     * </ul>
     * 
     * @throws Exception
     */
    protected void setUpJSFObjects()
    {
        setUpLifecycle();
        setUpApplication();
        setUpRenderKit();
    }

    /**
     * <p>Setup servlet objects that will be used for the test:</p>
     * 
     * <ul>
     * <li><code>config</code> (<code>MockServletConfig</code>)</li>
     * <li><code>servletContext</code> (<code>MockServletContext</code>)</li>
     * </ul>
     * 
     * @throws Exception
     */
    protected void setUpServletContext()
    {
        servletContext = new MockServletContext();
        config = new MockServletConfig(servletContext);
        webContainer = new MockWebContainer();
        servletContext.setWebContainer(webContainer);
        // Subscribe the container to receive session creation and destroy events.
        webContainer.subscribeListener(this);
    }
    
    /**
     * <p>Setup servlet objects that will be used for the test:</p>
     * 
     * <ul>
     * <li><code>request</code> (<code>MockHttpServletRequest</code></li>
     * <li><code>response</code> (<code>MockHttpServletResponse</code>)</li>
     * </ul>
     * 
     * @throws Exception
     */
    protected void setUpRequest()
    {
        request = lastSession == null ? 
            new MockHttpServletRequest() : new MockHttpServletRequest(lastSession);
        requestInitializedCalled = false;
        request.setServletContext(servletContext);
        response = new MockHttpServletResponse();
    }
    
    protected void doRequestInitialized()
    {
        if (!requestInitializedCalled)
        {
            webContainer.requestInitialized(new ServletRequestEvent(servletContext, request));
            requestInitializedCalled = true;
        }
    }
    
    public void startRequest()
    {
        setUpRequest();        
        doRequestInitialized();
        
        setUpFacesContext();
        setUpDefaultView();
    }
    
    public void startSession()
    {
        if (request != null)
        {
            //Create it indirectly through call to getSession(...)
            request.getSession(true);
        }
    }
    
    public void endSession()
    {
        MockHttpSession session = (MockHttpSession) request.getSession(false);
        if (session != null)
        {
            session.invalidate();
        }
    }
    
    public void sessionCreated(HttpSessionEvent se)
    {
        lastSession = (MockHttpSession) se.getSession();
        //No op
    }

    public void sessionDestroyed(HttpSessionEvent se)
    {
        lastSession = null;
    }
    
    /**
     * <p>Set JSF factories using FactoryFinder method setFactory.</p>
     * 
     * @throws Exception
     */
    protected void setFactories()
    {
        FactoryFinder.setFactory(FactoryFinder.APPLICATION_FACTORY,
                "org.apache.myfaces.test.mock.MockApplicationFactory");
        FactoryFinder.setFactory(FactoryFinder.FACES_CONTEXT_FACTORY,
                "org.apache.myfaces.test.mock.MockFacesContextFactory");
        FactoryFinder.setFactory(FactoryFinder.LIFECYCLE_FACTORY,
                "org.apache.myfaces.test.mock.lifecycle.MockLifecycleFactory");
        FactoryFinder.setFactory(FactoryFinder.RENDER_KIT_FACTORY,
                "org.apache.myfaces.test.mock.MockRenderKitFactory");
    }

    /**
     * Setup the <code>lifecycle</code> and <code>lifecycleFactory</code>
     * variables.
     * 
     * @throws Exception
     */
    protected void setUpLifecycle()
    {
        lifecycleFactory = (MockLifecycleFactory) FactoryFinder
                .getFactory(FactoryFinder.LIFECYCLE_FACTORY);
        lifecycle = (MockLifecycle) lifecycleFactory
                .getLifecycle(LifecycleFactory.DEFAULT_LIFECYCLE);
    }

    /**
     * Setup the <code>facesContextFactory</code> and <code>facesContext</code>
     * variable. Before end, by default it override <code>externalContext</code>
     * variable from the value retrieved from facesContext.getExternalContext(),
     * because sometimes it is possible facesContext overrides externalContext
     * internally.
     * 
     * @throws Exception
     */
    protected void setUpFacesContext()
    {
        facesContextFactory = (MockFacesContextFactory) FactoryFinder
                .getFactory(FactoryFinder.FACES_CONTEXT_FACTORY);
        facesContext = (MockFacesContext) facesContextFactory.getFacesContext(
                servletContext, request, response, lifecycle);
        if (facesContext.getExternalContext() != null)
        {
            externalContext = (MockExternalContext) facesContext
                    .getExternalContext();
        }
        else
        {
            externalContext = new MockExternalContext(servletContext, request,
                response);
            facesContext.setExternalContext(externalContext);
        }
        facesContext.setApplication(application);
    }

    /**
     * By default, create an instance of UIViewRoot, set its viewId as "/viewId"
     * and assign it to the current facesContext.
     * 
     * @throws Exception
     */
    protected void setUpDefaultView()
    {
        UIViewRoot root = new UIViewRoot();
        root.setViewId("/viewId");
        root.setLocale(getLocale());
        root.setRenderKitId(RenderKitFactory.HTML_BASIC_RENDER_KIT);
        facesContext.setViewRoot(root);
    }
    
    protected Locale getLocale()
    {
        return Locale.getDefault();
    }    

    /**
     * Setup the <code>application</code> variable and before
     * the end by default it is assigned to the <code>facesContext</code>
     * variable, calling <code>facesContext.setApplication(application)</code>
     * 
     * @throws Exception
     */
    protected void setUpApplication()
    {
        ApplicationFactory applicationFactory = (ApplicationFactory) FactoryFinder
                .getFactory(FactoryFinder.APPLICATION_FACTORY);
        application = (MockApplication) applicationFactory.getApplication();
    }

    /**
     * Setup the <code>renderKit</code> variable. This is a good place to use
     * <code>ConfigParser</code> to register converters, validators, components
     * or renderkits.
     * 
     * @throws Exception
     */
    protected void setUpRenderKit()
    {
        RenderKitFactory renderKitFactory = (RenderKitFactory) FactoryFinder
                .getFactory(FactoryFinder.RENDER_KIT_FACTORY);
        renderKit = new MockRenderKit();
        renderKitFactory.addRenderKit(RenderKitFactory.HTML_BASIC_RENDER_KIT,
                renderKit);
    }

    public MockApplication getApplication()
    {
        return application;
    }
    
    public MockExternalContext getExternalContext()
    {
        return externalContext;
    }

    public MockFacesContext getFacesContext()
    {
        return facesContext;
    }

    public MockHttpServletRequest getRequest()
    {
        return request;
    }

    public MockHttpServletResponse getResponse()
    {
        return response;
    }

    public MockServletContext getServletContext()
    {
        return servletContext;
    }
    
    /**
     * @return the webContainer
     */
    public MockWebContainer getWebContainer()
    {
        return webContainer;
    }

    /**
     * This method call doRequestDestroyed() and then tearDownRequest(). 
     */
    public final void endRequest()
    {
        
        doRequestDestroyed();
        tearDownRequest();
    }

    protected void doRequestDestroyed()
    {
        if (request != null)
        {
            webContainer.requestDestroyed(new ServletRequestEvent(servletContext, request));
        }
    }

    protected void tearDownRequest()
    {
        if (facesContext != null)
        {
            facesContext.release();
        }
        externalContext = null;
        facesContext = null;
        request = null;
        response = null;
    }
    
    /**
     * <p>Tear down instance variables required by this test case.</p>
     */
    public void tearDown()
    {
        if (facesContext != null)
        {
            facesContext.release();
        }
        application = null;
        config = null;
        externalContext = null;
        facesContext = null;
        lifecycle = null;
        lifecycleFactory = null;
        renderKit = null;
        request = null;
        response = null;
        servletContext = null;
        lastSession = null;
        webContainer = null;
        FactoryFinder.releaseFactories();
        ResourceBundleVarNames.resetNames();
    }

    // ------------------------------------------------------ Instance Variables

    // Mock object instances for our tests
    protected MockApplication application = null;
    protected MockServletConfig config = null;
    protected MockExternalContext externalContext = null;
    protected MockFacesContext facesContext = null;
    protected MockFacesContextFactory facesContextFactory = null;
    protected MockLifecycle lifecycle = null;
    protected MockLifecycleFactory lifecycleFactory = null;
    protected MockRenderKit renderKit = null;
    protected MockHttpServletRequest request = null;
    protected boolean requestInitializedCalled = false;
    protected MockHttpServletResponse response = null;
    protected MockHttpSession lastSession = null;
    protected MockServletContext servletContext = null;
    private MockWebContainer webContainer = null;

}
