/*
 * 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.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.Set;

import javax.faces.FacesException;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/**
 * <p>Mock implementation of <code>ExternalContext</code>.</p>
 *
 * $Id$
 */

public class MockExternalContext extends ExternalContext
{

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

    /**
     * <p>Construct a wrapper instance.</p>
     *
     * @param context <code>ServletContext</code> for this application
     * @param request <code>HttpServetRequest</code> for this request
     * @param response <code>HttpServletResponse</code> for this request
     */
    public MockExternalContext(ServletContext context,
                               HttpServletRequest request,
                               HttpServletResponse response)
    {

        this.context = context;
        this.request = request;
        this.response = response;
        this.applicationMap = null;
        this.initParameterMap = null;
        this.requestMap = null;
        this.requestCookieMap = null;
        this.requestHeaderMap = null;
        this.requestParameterMap = null;
        this.requestParameterValuesMap = null;
        this.requestHeaderValuesMap = null;
        this.sessionMap = null;
    }

    // ----------------------------------------------------- Mock Object Methods

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

    protected ServletContext context;
    protected HttpServletRequest request;
    protected HttpServletResponse response;
    private Map applicationMap;
    private Map initParameterMap;
    private Map requestMap;
    private Map requestCookieMap;
    private Map requestHeaderMap;
    private Map requestParameterMap;
    private Map requestParameterValuesMap;
    private Map requestHeaderValuesMap;
    private Map sessionMap;

    // ------------------------------------------------- setters for the mock object

    /**
     * <p>Add a new cookie for this request.</p>
     *
     * @param cookie The new cookie
     */
    public void addRequestCookieMap(Cookie cookie)
    {
        Map map = getRequestCookieMap();
        if (request instanceof MockHttpServletRequest &&
            map instanceof _CookieMap)
        {
            ((MockHttpServletRequest)request).addCookie(cookie);
        }
        else
        {
            map.put(cookie.getName(), cookie);
        }
    }

    /**
     * <p>Set the request cookie map for this request.</p>
     *
     * @param map The new request cookie map
     */
    public void setRequestCookieMap(Map map)
    {
        requestCookieMap = map;
    }

    /**
     * <p>Add the specified request parameter for this request.</p>
     *
     * @param key Parameter name
     * @param value Parameter value
     */
    public void addRequestParameterMap(String key, String value)
    {
        Map map = getRequestParameterMap();
        if (request instanceof MockHttpServletRequest &&
            map instanceof _RequestParameterMap)
        {
            ((MockHttpServletRequest)request).addParameter(key, value);
        }
        else
        {
            map.put(key, value);
        }
    }

    /**
     * <p>Set the request parameter map for this request.</p>
     *
     * @param map The new request parameter map
     */
    public void setRequestParameterMap(Map map)
    {
        requestParameterMap = map;
    }

    /**
     * <p>Add the specified request header for this request.</p>
     *
     * @param key Parameter name
     * @param value Parameter value
     */
    public void addRequestHeader(String key, String value)
    {
        Map map = getRequestHeaderMap();
        if (request instanceof MockHttpServletRequest &&
            map instanceof _RequestHeaderMap)
        {
            ((MockHttpServletRequest)request).addHeader(key, value);
        }
        else
        {
            map.put(key, value);
        }
    }

    /**
     * <p>Set the request header map for this request.</p>
     *
     * @param map The new request header map
     */
    public void setRequestHeaderMap(Map map)
    {
        requestHeaderMap = map;
    }

    // ------------------------------------------------- ExternalContext Methods

    /** {@inheritDoc} */
    public void dispatch(String requestURI) throws IOException, FacesException
    {
        RequestDispatcher requestDispatcher = request
                .getRequestDispatcher(requestURI);
        // If there is no dispatcher, send NOT_FOUND
        if (requestDispatcher == null)
        {
            ((HttpServletResponse) response)
                    .sendError(HttpServletResponse.SC_NOT_FOUND);
            return;
        }
        try
        {
            requestDispatcher.forward(request, response);
        }
        catch (ServletException e)
        {
            if (e.getMessage() != null)
            {
                throw new FacesException(e.getMessage(), e);
            }
            throw new FacesException(e);
        }
    }

    /** {@inheritDoc} */
    public String encodeActionURL(String sb)
    {
        return sb;
    }

    /** {@inheritDoc} */
    public String encodeNamespace(String aValue)
    {
        return aValue;
    }

    /** {@inheritDoc} */
    public String encodeResourceURL(String sb)
    {
        return sb;
    }

    /** {@inheritDoc} */
    public Map getApplicationMap()
    {
        if (applicationMap == null)
        {
            applicationMap = new _ApplicationMap(context);
        }
        return applicationMap;
    }

    /** {@inheritDoc} */
    public String getAuthType()
    {
        return request.getAuthType();
    }

    /** {@inheritDoc} */
    public Object getContext()
    {
        return context;
    }

    /** {@inheritDoc} */
    public String getInitParameter(String name)
    {
        return context.getInitParameter(name);
    }

    /** {@inheritDoc} */
    public Map getInitParameterMap()
    {
        if (initParameterMap == null)
        {
            initParameterMap = new _InitParameterMap(context);
        }
        return initParameterMap;
    }

    /** {@inheritDoc} */
    public String getRemoteUser()
    {
        return request.getRemoteUser();
    }

    /** {@inheritDoc} */
    public Object getRequest()
    {
        return request;
    }

    /** {@inheritDoc} */
    public String getRequestContextPath()
    {
        return request.getContextPath();
    }

    /** {@inheritDoc} */
    public Map getRequestCookieMap()
    {
        if (requestCookieMap == null)
        {
            requestCookieMap = new _CookieMap(request);
        }
        return requestCookieMap;
    }

    /** {@inheritDoc} */
    public Map getRequestHeaderMap()
    {
        if (requestHeaderMap == null)
        {
            requestHeaderMap = new _RequestHeaderMap(request);
        }
        return requestHeaderMap;
    }

    /** {@inheritDoc} */
    public Map getRequestHeaderValuesMap()
    {
        if (requestHeaderValuesMap == null)
        {
            requestHeaderValuesMap = new _RequestHeaderValuesMap(request);
        }
        return requestHeaderValuesMap;
    }

    /** {@inheritDoc} */
    public Locale getRequestLocale()
    {
        return request.getLocale();
    }

    /** {@inheritDoc} */
    public Iterator getRequestLocales()
    {
        return new LocalesIterator(request.getLocales());
    }

    /** {@inheritDoc} */
    public Map getRequestMap()
    {
        if (requestMap == null)
        {
            requestMap = new _RequestMap(request);
        }
        return requestMap;
    }

    /** {@inheritDoc} */
    public Map getRequestParameterMap()
    {
        if (requestParameterMap == null)
        {
            requestParameterMap = new _RequestParameterMap(request);
        }
        return requestParameterMap;
    }

    /** {@inheritDoc} */
    public Iterator getRequestParameterNames()
    {
        final Enumeration enumer = request.getParameterNames();
        Iterator it = new Iterator()
        {
            public boolean hasNext()
            {
                return enumer.hasMoreElements();
            }

            public Object next()
            {
                return enumer.nextElement();
            }

            public void remove()
            {
                throw new UnsupportedOperationException(this.getClass()
                        .getName()
                        + " UnsupportedOperationException");
            }
        };
        return it;
    }

    /** {@inheritDoc} */
    public Map getRequestParameterValuesMap()
    {
        if (requestParameterValuesMap == null)
        {
            requestParameterValuesMap = new _RequestParameterValuesMap(request);
        }
        return requestParameterValuesMap;
    }

    /** {@inheritDoc} */
    public String getRequestPathInfo()
    {
        return request.getPathInfo();
    }

    /** {@inheritDoc} */
    public String getRequestServletPath()
    {
        return request.getServletPath();
    }

    /** {@inheritDoc} */
    public URL getResource(String path) throws MalformedURLException
    {
        return context.getResource(path);
    }

    /** {@inheritDoc} */
    public InputStream getResourceAsStream(String path)
    {
        return context.getResourceAsStream(path);
    }

    /** {@inheritDoc} */
    public Set getResourcePaths(String path)
    {
        return context.getResourcePaths(path);
    }

    /** {@inheritDoc} */
    public Object getResponse()
    {
        return response;
    }

    /** {@inheritDoc} */
    public Object getSession(boolean create)
    {
        return request.getSession(create);
    }

    /** {@inheritDoc} */
    public Map getSessionMap()
    {
        if (sessionMap == null)
        {
            HttpSession session = request.getSession(true);
            sessionMap = new MockSessionMap(session);
        }
        return sessionMap;
    }

    /** {@inheritDoc} */
    public java.security.Principal getUserPrincipal()
    {
        return request.getUserPrincipal();
    }

    /** {@inheritDoc} */
    public boolean isUserInRole(String role)
    {
        return request.isUserInRole(role);
    }

    /** {@inheritDoc} */
    public void log(String message)
    {
        context.log(message);
    }

    /** {@inheritDoc} */
    public void log(String message, Throwable throwable)
    {
        context.log(message, throwable);
    }

    /** {@inheritDoc} */
    public void redirect(String requestURI) throws IOException
    {
        response.sendRedirect(requestURI);
        FacesContext.getCurrentInstance().responseComplete();
    }

    /**
     * <p>Iterator implementation that wraps an enumeration
     * of Locales for the current request.</p>
     */
    private class LocalesIterator implements Iterator
    {

        /**
         * <p>Construct an iterator wrapping the specified
         * enumeration.</p>
         *
         * @param locales Locales enumeration to wrap
         */
        public LocalesIterator(Enumeration locales)
        {
            this.locales = locales;
        }

        /**
         * <p>The enumeration to be wrapped.</p>
         */
        private Enumeration locales;

        /** {@inheritDoc} */
        public boolean hasNext()
        {
            return locales.hasMoreElements();
        }

        /** {@inheritDoc} */
        public Object next()
        {
            return locales.nextElement();
        }

        /** {@inheritDoc} */
        public void remove()
        {
            throw new UnsupportedOperationException();
        }

    }

}
