package com.mockobjects.servlet;

import com.mockobjects.*;

import javax.servlet.ServletInputStream;
import javax.servlet.RequestDispatcher;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.servlet.http.Cookie;
import java.util.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.security.Principal;

import com.mockobjects.ReturnValue;

/**
 * @version $Revision: 1.16 $
 */
public class MockHttpServletRequest extends MockObject
    implements HttpServletRequest {

    private final ReturnObjectBag myParameters = new ReturnObjectBag("parameters");
    private final ReturnObjectBag myHeaders = new ReturnObjectBag("headers");
    private final ReturnValue myHttpSession = new ReturnValue("session");
    private final ReturnValue myContentTypeToReturn = new ReturnValue("content type");
    private final ReturnValue myContextPath = new ReturnValue("context path");
    private final ReturnValue myPathInfo = new ReturnValue("path info");
    private final ReturnValue myRemoteAddress = new ReturnValue("remote address");
    private final ReturnValue myRequestURI = new ReturnValue("request uri");
    private final ReturnValue method = new ReturnValue("method");
    private final ReturnValue protocol = new ReturnValue("protocol");
    private final ReturnValue inputStream = new ReturnValue("input stream");
    private final ReturnValue myUserPrincipal = new ReturnValue("user principal");
    private final ReturnValue myAttributesNames = new ReturnValue("attribute names");
    private final ReturnValue queryString = new ReturnValue("query string");
    private final ReturnValue scheme = new ReturnValue("scheme");
    private final ReturnValue serverName = new ReturnValue("server name");
    private final ReturnValue reader = new ReturnValue("reader");
    private final ExpectationSet mySetAttributes = new ExpectationSet("HttpServletRequest.setAttribute");
    private final ExpectationSet myRemoveAttributes = new ExpectationSet("HttpServletRequest.removeAttribute");
    private final ReturnObjectList myAttributesToReturn = new ReturnObjectList("attributes");
    private final ExpectationValue myContentType = new ExpectationValue("content type");
    private final ExpectationList myGetAttributeNames = new ExpectationList("get attribute names");
    private final ReturnValue servletPath = new ReturnValue("servlet path");
    private final ReturnValue parameterMap = new ReturnValue("parameter map");
    private final ReturnValue myParameterNames = new ReturnValue("parameter names");
    private final ReturnValue requestDispatcher = new ReturnValue("request dispatcher");
    private final ExpectationValue requestDispatcherURI = new ExpectationValue("request dispatcher uri");
    private final ExpectationValue createSession = new ExpectationValue("create session");

    public void setupGetAttribute(Object anAttributeToReturn) {
        myAttributesToReturn.addObjectToReturn(anAttributeToReturn);
    }

    public void addExpectedGetAttributeName(String anAttributeName) {
        myGetAttributeNames.addExpected(anAttributeName);
    }

    public Object getAttribute(String anAttributeName) {
        myGetAttributeNames.addActual(anAttributeName);
        return myAttributesToReturn.nextReturnObject();
    }

    public void setupGetAttrubuteNames(Enumeration attributeNames) {
        myAttributesNames.setValue(attributeNames);
    }

    public Enumeration getAttributeNames() {
        return (Enumeration) myAttributesNames.getValue();
    }

    public String getAuthType() {
        notImplemented();
        return null;
    }

    public String getCharacterEncoding() {
        notImplemented();
        return null;
    }

    public int getContentLength() {
        notImplemented();
        return 0;
    }

    public String getContentType() {
        return (String) myContentTypeToReturn.getValue();
    }

    public void setupGetContentType(String aContentType) {
        myContentTypeToReturn.setValue(aContentType);
    }

    public void setExpectedContentType(String aContentType) {
        this.myContentType.setExpected(aContentType);
    }

    public void setContentType(String contentType) {
        this.myContentType.setActual(contentType);
    }

    public String getContextPath() {
        return (String) myContextPath.getValue();
    }

    public void setupGetContextPath(String contextPath) {
        myContextPath.setValue(contextPath);
    }

    public Cookie[] getCookies() {
        notImplemented();
        return null;
    }

    public long getDateHeader(String arg1) {
        notImplemented();
        return 0;
    }

    public String getHeader(String key) {
        return (String) myHeaders.getNextReturnObject(key);
    }

    public Enumeration getHeaderNames() {
        notImplemented();
        return null;
    }

    public Enumeration getHeaders(String arg1) {
        notImplemented();
        return null;
    }

    public void setupGetInputStream(ServletInputStream inputStream) {
        this.inputStream.setValue(inputStream);
    }

    public ServletInputStream getInputStream()
        throws IOException {
        return (ServletInputStream) inputStream.getValue();
    }

    public int getIntHeader(String arg1) {
        notImplemented();
        return 0;
    }

    public Locale getLocale() {
        notImplemented();
        return null;
    }

    public Enumeration getLocales() {
        notImplemented();
        return null;
    }

    public void setupGetMethod(String aMethod) {
        this.method.setValue(aMethod);
    }

    public String getMethod() {
        return (String) method.getValue();
    }

    public String getParameter(String paramName) {
        String[] values = getParameterValues(paramName);
        if (values == null)
            return null;

        return values[0];
    }

    public void setupGetParameterNames(Enumeration names) {
        this.myParameterNames.setValue(names);
    }

    public Enumeration getParameterNames() {
        return (Enumeration) myParameterNames.getValue();
    }

    public String[] getParameterValues(String key) {
        return (String[]) myParameters.getNextReturnObject(key);
    }

    public String getPathInfo() {
        return (String) myPathInfo.getValue();
    }

    public String getPathTranslated() {
        notImplemented();
        return null;
    }

    public String getProtocol() {
        return (String) protocol.getValue();
    }

    public void setupGetProtocol(String protocol) {
        this.protocol.setValue(protocol);
    }

    public String getQueryString() {
        return (String) queryString.getValue();
    }

    public BufferedReader getReader() {
        return (BufferedReader) reader.getValue();
    }

    public void setupGetReader(BufferedReader reader) throws IOException {
        this.reader.setValue(reader);
    }

    public String getRealPath(String arg1) {
        notImplemented();
        return null;
    }

    public void setupGetRemoteAddr(String remoteAddress) {
        this.myRemoteAddress.setValue(remoteAddress);
    }

    public String getRemoteAddr() {
        return (String) myRemoteAddress.getValue();
    }

    public String getRemoteHost() {
        notImplemented();
        return null;
    }

    public String getRemoteUser() {
        notImplemented();
        return null;
    }

    public void setupGetRequestDispatcher(RequestDispatcher requestDispatcher) {
        this.requestDispatcher.setValue(requestDispatcher);
    }

    public RequestDispatcher getRequestDispatcher(String uri) {
        this.requestDispatcherURI.setActual(uri);
        return (RequestDispatcher) requestDispatcher.getValue();
    }

    public void setExpectedRequestDispatcherURI(String uri) {
        this.requestDispatcherURI.setExpected(uri);
    }

    public String getRequestedSessionId() {
        notImplemented();
        return null;
    }

    public void setupGetRequestURI(String aRequestURI) {
        myRequestURI.setValue(aRequestURI);
    }

    public String getRequestURI() {
        return (String) myRequestURI.getValue();
    }

    public String getScheme() {
        return (String) scheme.getValue();
    }

    public String getServerName() {
        return (String) serverName.getValue();
    }

    public int getServerPort() {
        notImplemented();
        return 0;
    }

    public void setupGetServletPath(String path) {
        this.servletPath.setValue(path);
    }

    public String getServletPath() {
        return (String) servletPath.getValue();
    }

    public HttpSession getSession() {
        return (HttpSession) myHttpSession.getValue();
    }

    public void setSession(HttpSession httpSession) {
        this.myHttpSession.setValue(httpSession);
    }

    public void setExpectedCreateSession(boolean createSession) {
        this.createSession.setExpected(createSession);
    }

    public HttpSession getSession(boolean createSession) {
        this.createSession.setActual(createSession);
        return getSession();
    }

    public void setupGetUserPrincipal(Principal userPrincipal) {
        this.myUserPrincipal.setValue(userPrincipal);
    }

    public Principal getUserPrincipal() {
        return (Principal) myUserPrincipal.getValue();
    }

    public boolean isRequestedSessionIdFromCookie() {
        notImplemented();
        return false;
    }

    public boolean isRequestedSessionIdFromUrl() {
        notImplemented();
        return false;
    }

    public boolean isRequestedSessionIdFromURL() {
        notImplemented();
        return false;
    }

    public boolean isRequestedSessionIdValid() {
        notImplemented();
        return false;
    }

    public boolean isSecure() {
        notImplemented();
        return false;
    }

    public boolean isUserInRole(java.lang.String arg1) {
        notImplemented();
        return false;
    }

    public void setupRemoveAttribute(String anAttributeToRemove) {
        myRemoveAttributes.addExpected(anAttributeToRemove);
    }

    public void removeAttribute(String anAttributeToRemove) {
        myRemoveAttributes.addActual(anAttributeToRemove);
    }

    public void addExpectedSetAttribute(String attributeName,
        Object attributeValue) {
        mySetAttributes.addExpected(
            new MapEntry(attributeName, attributeValue));
    }

    public void setAttribute(String attributeName, Object attributeValue) {
        mySetAttributes.addActual(
            new MapEntry(attributeName, attributeValue));
    }

    public void setupAddParameter(String paramName, String[] values) {
        myParameters.putObjectToReturn(paramName, values);
    }

    public void setupAddParameter(String paramName, String value) {
        setupAddParameter(paramName, new String[]{value});
    }

    public void setupAddHeader(String headerName, String value) {
        myHeaders.putObjectToReturn(headerName, value);
    }

    public void setupPathInfo(String pathInfo) {
        myPathInfo.setValue(pathInfo);
    }

    public void setupQueryString(String aQueryString) {
        queryString.setValue(aQueryString);
    }

    public void setupScheme(String aScheme) {
        scheme.setValue(aScheme);
    }

    public void setupServerName(String aServerName) {
        serverName.setValue(aServerName);
    }

    public StringBuffer getRequestURL() {
        notImplemented();
        return null;
    }

    public void setCharacterEncoding(String s) {
        notImplemented();
    }

    public void setupGetParameterMap(Map map) {
        this.parameterMap.setValue(map);
    }

    public Map getParameterMap() {
        return (Map) parameterMap.getValue();
    }
}
