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

import java.beans.BeanInfo;
import java.io.IOException;

import javax.faces.FacesException;
import javax.faces.FactoryFinder;
import javax.faces.application.Application;
import javax.faces.application.Resource;
import javax.faces.application.ViewHandler;
import javax.faces.component.UIViewRoot;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.render.RenderKit;
import javax.faces.render.RenderKitFactory;
import javax.faces.view.StateManagementStrategy;
import javax.faces.view.ViewDeclarationLanguage;
import javax.faces.view.ViewMetadata;
import javax.servlet.http.HttpServletResponse;

import org.apache.myfaces.shared.application.InvalidViewIdException;

/**
 * It is a vdl that is just provided as fallback, to ensure if
 * viewHandler.createView(context, null) is called, an instance
 * is retrieved just like with jsp vdl, and it provides some methods
 * to hook a view instance for createView() and restoreView() methods.
 * 
 * In this way, it is possible to create view instance programatically
 * and simulate that it is generated by the vdl. 
 * 
 * @author Leonardo Uribe
 *
 */
public class MockDefaultViewDeclarationLanguage extends ViewDeclarationLanguage
{
    public static final String DUMMY_VIEW_CREATE_HOOK = "oam.dummy.create.UIViewRoot";
    public static final String DUMMY_VIEW_RESTORE_HOOK = "oam.dummy.restore.UIViewRoot";

    @Override
    public void buildView(FacesContext context, UIViewRoot view)
            throws IOException
    {
    }

    @Override
    public UIViewRoot createView(FacesContext context, String viewId)
    {
        if (context.getAttributes().containsKey(DUMMY_VIEW_CREATE_HOOK))
        {
            UIViewRoot root = (UIViewRoot) context.getAttributes().remove(DUMMY_VIEW_CREATE_HOOK);
            Application application = context.getApplication();
            ViewHandler handler = application.getViewHandler();
            root.setLocale(handler.calculateLocale(context));
            root.setRenderKitId(handler.calculateRenderKitId(context));
            root.setViewId(viewId);
            return root;
        }
        else
        {
            try
            {
                viewId = calculateViewId(context, viewId);
                
                Application application = context.getApplication();
                // Create a new UIViewRoot object instance using Application.createComponent(UIViewRoot.COMPONENT_TYPE).
                UIViewRoot newViewRoot = (UIViewRoot) application.createComponent(UIViewRoot.COMPONENT_TYPE);
                UIViewRoot oldViewRoot = context.getViewRoot();
                if (oldViewRoot == null)
                {
                    // If not, this method must call calculateLocale() and calculateRenderKitId(), and store the results
                    // as the values of the locale and renderKitId, proeprties, respectively, of the newly created
                    // UIViewRoot.
                    ViewHandler handler = application.getViewHandler();
                    newViewRoot.setLocale(handler.calculateLocale(context));
                    newViewRoot.setRenderKitId(handler.calculateRenderKitId(context));
                }
                else
                {
                    // If there is an existing UIViewRoot available on the FacesContext, 
                    //this method must copy its locale
                    // and renderKitId to this new view root
                    newViewRoot.setLocale(oldViewRoot.getLocale());
                    newViewRoot.setRenderKitId(oldViewRoot.getRenderKitId());
                }
                
                // TODO: VALIDATE - The spec is silent on the following line, but I feel bad if I don't set it
                newViewRoot.setViewId(viewId);
    
                return newViewRoot;
            }
            catch (InvalidViewIdException e)
            {
                // If no viewId could be identified, or the viewId is exactly equal to the servlet mapping, 
                // send the response error code SC_NOT_FOUND with a suitable message to the client.
                sendSourceNotFound(context, e.getMessage());
                
                // TODO: VALIDATE - Spec is silent on the return value when an error was sent
                return null;
            }
        }
    }
    
    /**
     * Calculates the effective view identifier for the specified raw view identifier.
     * 
     * @param context le current FacesContext
     * @param viewId the raw view identifier
     * 
     * @return the effective view identifier
     */
    protected String calculateViewId(FacesContext context, String viewId)
    {
        if (viewId != null)
        {
            throw new InvalidViewIdException();
        }
        return null;
    }
    
    protected void sendSourceNotFound(FacesContext context, String message)
    {
        HttpServletResponse response = (HttpServletResponse) context.getExternalContext().getResponse();
        try
        {
            context.responseComplete();
            response.sendError(HttpServletResponse.SC_NOT_FOUND, message);
        }
        catch (IOException ioe)
        {
            throw new FacesException(ioe);
        }
    }
    
    /**
     * Hook the passed instance on UIViewRoot, storing into facesContext attribute map,
     * so the next call to createView() will return that value.
     * 
     * @param context
     * @param root
     */
    public static void hookCreateView(FacesContext context, UIViewRoot root)
    {
        context.getAttributes().put(DUMMY_VIEW_CREATE_HOOK, root);
    }

    /**
     * Hook the passed instance on UIViewRoot, storing into facesContext attribute map,
     * so the next call to createView() will return that value.
     * 
     * @param context
     * @param root
     */
    public static void hookRestoreView(FacesContext context, UIViewRoot root)
    {
        context.getAttributes().put(DUMMY_VIEW_RESTORE_HOOK, root);
    }

    @Override
    public BeanInfo getComponentMetadata(FacesContext context,
            Resource componentResource)
    {
        return null;
    }

    @Override
    public Resource getScriptComponentResource(FacesContext context,
            Resource componentResource)
    {
        return null;
    }

    @Override
    public StateManagementStrategy getStateManagementStrategy(
            FacesContext context, String viewId)
    {
        return null;
    }

    @Override
    public ViewMetadata getViewMetadata(FacesContext context, String viewId)
    {
        return null;
    }

    @Override
    public void renderView(FacesContext context, UIViewRoot view)
            throws IOException
    {
        checkNull(context, "context");
        checkNull(view, "view");
        
        ExternalContext externalContext = context.getExternalContext();
        ResponseWriter responseWriter = context.getResponseWriter();
        if (responseWriter == null)
        {
            RenderKitFactory renderFactory = (RenderKitFactory) 
                FactoryFinder.getFactory(FactoryFinder.RENDER_KIT_FACTORY);
            RenderKit renderKit = renderFactory.getRenderKit(context, view.getRenderKitId());

            responseWriter = renderKit.createResponseWriter(externalContext.getResponseOutputWriter(), 
                    null, externalContext.getRequestCharacterEncoding());
            context.setResponseWriter(responseWriter);
        }

        // Now we actually render the document
        // Call startDocument() on the ResponseWriter.
        responseWriter.startDocument();

        view.encodeAll(context);
        
        // Call endDocument() on the ResponseWriter
        responseWriter.endDocument();
    
        responseWriter.flush();
    }

    @Override
    public UIViewRoot restoreView(FacesContext context, String viewId)
    {
        checkNull(context, "context");
        //checkNull(viewId, "viewId");

        if (context.getAttributes().containsKey(DUMMY_VIEW_RESTORE_HOOK))
        {
            UIViewRoot root = (UIViewRoot) context.getAttributes().remove(DUMMY_VIEW_RESTORE_HOOK);
            root.setViewId(viewId);
            return root;
        }
        else
        {
            Application application = context.getApplication();
            
            ViewHandler applicationViewHandler = application.getViewHandler();
            
            String renderKitId = applicationViewHandler.calculateRenderKitId(context);
    
            UIViewRoot viewRoot = application.getStateManager().restoreView(context, viewId, renderKitId);
    
            return viewRoot;
        }
    }
    
    protected void checkNull(final Object o, final String param)
    {
        if (o == null)
        {
            throw new NullPointerException(param + " can not be null.");
        }
    }
}
