/*
 * 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.BufferedReader;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.security.Principal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.TimeZone;
import java.util.Vector;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletRequestAttributeEvent;
import javax.servlet.ServletRequestAttributeListener;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;


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

public class MockHttpServletRequest implements HttpServletRequest {


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


    public MockHttpServletRequest() {

        super();

    }


    public MockHttpServletRequest(HttpSession session) {

        super();
        setHttpSession(session);

    }


    public MockHttpServletRequest(String contextPath, String servletPath,
                                  String pathInfo, String queryString) {

        super();
        setPathElements(contextPath, servletPath, pathInfo, queryString);

    }



    public MockHttpServletRequest(String contextPath, String servletPath,
                                  String pathInfo, String queryString,
                                  HttpSession session) {

        super();
        setPathElements(contextPath, servletPath, pathInfo, queryString);
        setHttpSession(session);

    }


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


    /**
     * <p>Add a new listener instance that should be notified about
     * attribute changes.</p>
     *
     * @param listener The new listener to register
     */
    public void addAttributeListener(ServletRequestAttributeListener listener) {
        attributeListeners.add(listener);
    }


    /**
     * <p>Add a date-valued header for this request.</p>
     *
     * @param name Header name
     * @param value Header value
     */
    public void addDateHeader(String name, long value) {

        headers.add(name + ": " + formatDate(value));

    }


    /**
     * <p>Add a String-valued header for this request.</p>
     *
     * @param name Header name
     * @param value Header value
     */
    public void addHeader(String name, String value) {

        headers.add(name + ": " + value);

    }


    /**
     * <p>Add an integer-valued header for this request.</p>
     *
     * @param name Header name
     * @param value Header value
     */
    public void addIntHeader(String name, int value) {

        headers.add(name + ": " + value);

    }


    /**
     * <p>Add a request parameter for this request.</p>
     *
     * @param name Parameter name
     * @param value Parameter value
     */
    public void addParameter(String name, String value) {

        String[] values = (String[]) parameters.get(name);
        if (values == null) {
            String[] results = new String[] { value };
            parameters.put(name, results);
            return;
        }
        String[] results = new String[values.length + 1];
        System.arraycopy(values, 0, results, 0, values.length);
        results[values.length] = value;
        parameters.put(name, results);

    }
    
    public void addCookie(Cookie c)
    {
        for (int i = 0; i < cookies.size(); i++)
        {
            if ( ((Cookie)cookies.get(i)).getName().equals(c.getName()) )
            {
                cookies.set(i, c);
                return;
            }
        }
        cookies.add(c);
    }

    /**
     * <p>Return the <code>ServletContext</code> associated with
     * this request.</p>
     */
    public ServletContext getServletContext() {

        return this.servletContext;

    }


    /**
     * <p>Set the <code>HttpSession</code> associated with this request.</p>
     *
     * @param session The new session
     */
    public void setHttpSession(HttpSession session) {

        this.session = session;

    }


    /**
     * <p>Set the <code>Locale</code> associated with this request.</p>
     *
     * @param locale The new locale
     */
    public void setLocale(Locale locale) {

        this.locale = locale;

    }


    /**
     * <p>Set the parsed path elements associated with this request.</p>
     *
     * @param contextPath The context path
     * @param servletPath The servlet path
     * @param pathInfo The extra path information
     * @param queryString The query string
     */
    public void setPathElements(String contextPath, String servletPath,
                                String pathInfo, String queryString) {

        this.contextPath = contextPath;
        this.servletPath = servletPath;
        this.pathInfo = pathInfo;
        this.queryString = queryString;

    }


    /**
     * <p>Set the <code>ServletContext</code> associated with this request.</p>
     *
     * @param servletContext The new servlet context
     */
    public void setServletContext(ServletContext servletContext) {

        this.servletContext = servletContext;

    }


    /**
     * <p>Set the <code>Principal</code> associated with this request.</p>
     *
     * @param principal The new Principal
     */
    public void setUserPrincipal(Principal principal) {

        this.principal = principal;

    }


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


    private List attributeListeners = new ArrayList();
    private HashMap attributes = new HashMap();
    private String contextPath = null;
    private List headers = new ArrayList();
    private Locale locale = null;
    private HashMap parameters = new HashMap();
    private String pathInfo = null;
    private Principal principal = null;
    private String queryString = null;
    private ServletContext servletContext = null;
    private String servletPath = null;
    private HttpSession session = null;
    private String characterEncoding = null;
    private ServletInputStream inputStream = null;
    private List cookies = new ArrayList();
    private Vector locales = null; 

    // ---------------------------------------------- HttpServletRequest Methods


    /** {@inheritDoc} */
    public String getAuthType() {

        throw new UnsupportedOperationException();

    }


    /** {@inheritDoc} */
    public String getContextPath() {

        return contextPath;

    }


    /** {@inheritDoc} */
    public Cookie[] getCookies() {

        Cookie[] array = new Cookie[cookies.size()];
        for (int i = 0; i < cookies.size(); i++)
        {
            array[i] = (Cookie) cookies.get(i);
        }
        return array;
    }


    /** {@inheritDoc} */
    public long getDateHeader(String name) {

        String match = name + ":";
        Iterator headers = this.headers.iterator();
        while (headers.hasNext()) {
            String header = (String) headers.next();
            if (header.startsWith(match)) {
                return parseDate(header.substring(match.length() + 1).trim());
            }
        }
        return (long) -1;

    }


    /** {@inheritDoc} */
    public String getHeader(String name) {

        String match = name + ":";
        Iterator headers = this.headers.iterator();
        while (headers.hasNext()) {
            String header = (String) headers.next();
            if (header.startsWith(match)) {
                return header.substring(match.length() + 1).trim();
            }
        }
        return null;

    }


    /** {@inheritDoc} */
    public Enumeration getHeaderNames() {

        Vector values = new Vector();
        Iterator headers = this.headers.iterator();
        while (headers.hasNext()) {
            String header = (String) headers.next();
            int colon = header.indexOf(':');
            if (colon >= 0) {
                String name = header.substring(0, colon).trim();
                if (!values.contains(name)) {
                    values.add(name);
                }
            }
        }
        return values.elements();

    }


    /** {@inheritDoc} */
    public Enumeration getHeaders(String name) {

        String match = name + ":";
        Vector values = new Vector();
        Iterator headers = this.headers.iterator();
        while (headers.hasNext()) {
            String header = (String) headers.next();
            if (header.startsWith(match)) {
                values.add(header.substring(match.length() + 1).trim());
            }
        }
        return values.elements();

    }


    /** {@inheritDoc} */
    public int getIntHeader(String name) {

        String match = name + ":";
        Iterator headers = this.headers.iterator();
        while (headers.hasNext()) {
            String header = (String) headers.next();
            if (header.startsWith(match)) {
                return Integer.parseInt(header.substring(match.length() + 1).trim());
            }
        }
        return -1;

    }


    /** {@inheritDoc} */
    public String getMethod() {

        throw new UnsupportedOperationException();

    }


    /** {@inheritDoc} */
    public String getPathInfo() {

        return pathInfo;

    }


    /** {@inheritDoc} */
    public String getPathTranslated() {

        throw new UnsupportedOperationException();

    }


    /** {@inheritDoc} */
    public String getQueryString() {

        return queryString;

    }


    /** {@inheritDoc} */
    public String getRemoteUser() {

        if (principal != null) {
            return principal.getName();
        } else {
            return null;
        }

    }


    /** {@inheritDoc} */
    public String getRequestedSessionId() {

        throw new UnsupportedOperationException();

    }


    /** {@inheritDoc} */
    public String getRequestURI() {

        StringBuffer sb = new StringBuffer();
        if (contextPath != null) {
            sb.append(contextPath);
        }
        if (servletPath != null) {
            sb.append(servletPath);
        }
        if (pathInfo != null) {
            sb.append(pathInfo);
        }
        if (sb.length() > 0) {
            return sb.toString();
        }
        throw new UnsupportedOperationException();

    }


    /** {@inheritDoc} */
    public StringBuffer getRequestURL() {

        throw new UnsupportedOperationException();

    }


    /** {@inheritDoc} */
    public String getServletPath() {

        return (servletPath);

    }


    /** {@inheritDoc} */
    public HttpSession getSession() {

        return getSession(true);

    }


    /** {@inheritDoc} */
    public HttpSession getSession(boolean create) {

        if (create && (session == null)) {
            this.session = new MockHttpSession(this.servletContext);
        }
        return session;

    }


    /** {@inheritDoc} */
    public Principal getUserPrincipal() {

        return principal;

    }


    /** {@inheritDoc} */
    public boolean isRequestedSessionIdFromCookie() {

        throw new UnsupportedOperationException();

    }


    /** {@inheritDoc} */
    public boolean isRequestedSessionIdFromUrl() {

        throw new UnsupportedOperationException();

    }


    /** {@inheritDoc} */
    public boolean isRequestedSessionIdFromURL() {

        throw new UnsupportedOperationException();

    }


    /** {@inheritDoc} */
    public boolean isRequestedSessionIdValid() {

        throw new UnsupportedOperationException();

    }


    /** {@inheritDoc} */
    public boolean isUserInRole(String role) {

        throw new UnsupportedOperationException();

    }


    // ------------------------------------------------- ServletRequest Methods


    /** {@inheritDoc} */
    public Object getAttribute(String name) {

        return attributes.get(name);

    }


    /** {@inheritDoc} */
    public Enumeration getAttributeNames() {

        return new MockEnumeration(attributes.keySet().iterator());

    }


    /** {@inheritDoc} */
    public String getCharacterEncoding() {

        return characterEncoding;

    }


    /** {@inheritDoc} */
    public int getContentLength() {

        throw new UnsupportedOperationException();

    }


    /** {@inheritDoc} */
    public String getContentType() {

        throw new UnsupportedOperationException();

    }


    /** {@inheritDoc} */
    public ServletInputStream getInputStream()
    {
        return this.inputStream;
    }
    
    public void setInputStream(MockServletInputStream stream)
    {
        this.inputStream = stream;
    }

    /** {@inheritDoc} */
    public Locale getLocale() {

        return locale;

    }


    /** {@inheritDoc} */
    public Enumeration getLocales()
    {
        if (this.locales == null)
        {
            locales = new Vector(Arrays.asList(Locale
                    .getAvailableLocales()));
        }
        return this.locales.elements();
    }


    /** {@inheritDoc} */
    public String getLocalAddr() {

        throw new UnsupportedOperationException();

    }


    /** {@inheritDoc} */
    public String getLocalName() {

        throw new UnsupportedOperationException();

    }


    /** {@inheritDoc} */
    public int getLocalPort() {

        throw new UnsupportedOperationException();

    }


    /** {@inheritDoc} */
    public String getParameter(String name) {

        String[] values = (String[]) parameters.get(name);
        if (values != null) {
            return values[0];
        } else {
            return null;
        }

    }


    /** {@inheritDoc} */
    public Map getParameterMap() {

        return parameters;

    }


    /** {@inheritDoc} */
    public Enumeration getParameterNames() {

        return new MockEnumeration(parameters.keySet().iterator());

    }


    /** {@inheritDoc} */
    public String[] getParameterValues(String name) {

        return (String[]) parameters.get(name);

    }


    /** {@inheritDoc} */
    public String getProtocol() {

        throw new UnsupportedOperationException();

    }


    /** {@inheritDoc} */
    public BufferedReader getReader()
    {
        if (this.inputStream != null) {
            try{
                Reader sourceReader = (this.characterEncoding != null) ? new InputStreamReader(
                        this.inputStream, this.characterEncoding)
                        : new InputStreamReader(this.inputStream);
                return new BufferedReader(sourceReader);
            }
            catch(UnsupportedEncodingException e)
            {
                throw new RuntimeException(e);
            }
        } else {
            return null;
        }
    }


    /** {@inheritDoc} */
    public String getRealPath(String path) {

        throw new UnsupportedOperationException();

    }


    /** {@inheritDoc} */
    public String getRemoteAddr() {

        // i figure testing never assumes a specific remote - so anything works
        return "1.2.3.4";

    }


    /** {@inheritDoc} */
    public String getRemoteHost() {

        // i figure testing never assumes a specific remote - so anything works
        return "MyfacesServer";

    }


    /** {@inheritDoc} */
    public int getRemotePort() {

        // i figure testing never assumes a specific remote - so anything works
        return 46123;

    }


    /** {@inheritDoc} */
    public RequestDispatcher getRequestDispatcher(String path)
    {
        return servletContext.getRequestDispatcher(path);
    }


    /** {@inheritDoc} */
    public String getScheme() {

        return ("http");

    }


    /** {@inheritDoc} */
    public String getServerName() {

        return ("localhost");

    }


    /** {@inheritDoc} */
    public int getServerPort() {

        return (8080);

    }


    /** {@inheritDoc} */
    public boolean isSecure() {

        return false;

    }


    /** {@inheritDoc} */
    public void removeAttribute(String name) {

        if (attributes.containsKey(name)) {
            Object value = attributes.remove(name);
            fireAttributeRemoved(name, value);
        }

    }


    /** {@inheritDoc} */
    public void setAttribute(String name, Object value) {

        if (name == null) {
            throw new IllegalArgumentException("Attribute name cannot be null");
        }
        if (value == null) {
            removeAttribute(name);
            return;
        }
        if (attributes.containsKey(name)) {
            Object oldValue = attributes.get(name);
            attributes.put(name, value);
            fireAttributeReplaced(name, oldValue);
        } else {
            attributes.put(name, value);
            fireAttributeAdded(name, value);
        }

    }


    /** {@inheritDoc} */
    public void setCharacterEncoding(String characterEncoding) {

        this.characterEncoding = characterEncoding;

    }


    // --------------------------------------------------------- Private Methods


    /**
     * <p>Fire an attribute added event to interested listeners.</p>
     *
     * @param key Attribute key whose value was added
     * @param value The new attribute value
     */
    private void fireAttributeAdded(String key, Object value) {
        if (attributeListeners.size() < 1) {
            return;
        }
        ServletRequestAttributeEvent event =
                new ServletRequestAttributeEvent(getServletContext(), this, key, value);
        Iterator listeners = attributeListeners.iterator();
        while (listeners.hasNext()) {
            ServletRequestAttributeListener listener =
                    (ServletRequestAttributeListener) listeners.next();
            listener.attributeAdded(event);
        }
    }


    /**
     * <p>Fire an attribute removed event to interested listeners.</p>
     *
     * @param key Attribute key whose value was removed
     * @param value Attribute value that was removed
     */
    private void fireAttributeRemoved(String key, Object value) {
        if (attributeListeners.size() < 1) {
            return;
        }
        ServletRequestAttributeEvent event =
                new ServletRequestAttributeEvent(getServletContext(), this, key, value);
        Iterator listeners = attributeListeners.iterator();
        while (listeners.hasNext()) {
            ServletRequestAttributeListener listener =
                    (ServletRequestAttributeListener) listeners.next();
            listener.attributeRemoved(event);
        }
    }


    /**
     * <p>Fire an attribute replaced event to interested listeners.</p>
     *
     * @param key Attribute key whose value was replaced
     * @param value The original value
     */
    private void fireAttributeReplaced(String key, Object value) {
        if (attributeListeners.size() < 1) {
            return;
        }
        ServletRequestAttributeEvent event =
                new ServletRequestAttributeEvent(getServletContext(), this, key, value);
        Iterator listeners = attributeListeners.iterator();
        while (listeners.hasNext()) {
            ServletRequestAttributeListener listener =
                    (ServletRequestAttributeListener) listeners.next();
            listener.attributeReplaced(event);
        }
    }


    /**
     * <p>The date formatting helper we will use in <code>httpTimestamp()</code>.
     * Note that usage of this helper must be synchronized.</p>
     */
    private static SimpleDateFormat format =
            new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz");
    static {
        format.setTimeZone(TimeZone.getTimeZone("GMT"));
    }


    /**
     * <p>Return a properly formatted String version of the specified
     * date/time, formatted as required by the HTTP specification.</p>
     *
     * @param date Date/time, expressed as milliseconds since the epoch
     */
    private String formatDate(long date) {
        return format.format(new Date(date));
    }


    /**
     * <p>Return a date/time value, parsed from the specified String.</p>
     *
     * @param date Date/time, expressed as a String
     */
    private long parseDate(String date) {
        try {
            return format.parse(date).getTime();
        } catch (ParseException e) {
            throw new IllegalArgumentException(date);
        }
    }


}
