package com.mockobjects.servlet;

import com.mockobjects.*;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Locale;

public class MockHttpServletResponse extends MockObject
    implements HttpServletResponse {

    private final ExpectationList myContentTypes =
        new ExpectationList("MockHttpServletResponse.setContentType");
    private final ExpectationList myHeaders =
        new ExpectationList("MockHttpServletResponse.setHeader");
    private final ExpectationCounter mySetStatusCalls =
        new ExpectationCounter("MockHttpServletResponse.setStatus");
    private final ExpectationList myRedirects =
        new ExpectationList("MockHttpServletResponse.sendRedirect");
    private MockServletOutputStream myOutputStream =
        new MockServletOutputStream();
    private final ExpectationValue myErrorCode =
        new ExpectationValue("MockHttpServletResponse.sendError");
    private final ExpectationValue myErrorMessage =
        new ExpectationValue("MockHttpServletResponse.sendError");
    private final ExpectationValue length = new ExpectationValue("MockHttpServletResponse.length");

    /**
     * Not Implemented
     */
    public void addCookie(Cookie arg1) {
        notImplemented();
    }

    /**
     * Not Implemented
     */
    public void addDateHeader(String arg1, long arg2) {
        notImplemented();
    }

    /**
     * Not Implemented
     */
    public void addHeader(String arg1, String arg2) {
        notImplemented();
    }

    /**
     * Not Implemented
     */
    public void addIntHeader(String arg1, int arg2) {
        notImplemented();
    }

    /**
     * Not Implemented
     */
    public boolean containsHeader(String arg1) {
        notImplemented();
        return false;
    }

    /**
     * Not Implemented
     */
    public String encodeRedirectUrl(String arg1) {
        notImplemented();
        return null;
    }

    /**
     * Not Implemented
     */
    public String encodeRedirectURL(String arg1) {
        notImplemented();
        return null;
    }

    /**
     * Not Implemented
     */
    public String encodeUrl(String arg1) {
        notImplemented();
        return null;
    }

    /**
     * Not Implemented
     */
    public String encodeURL(String arg1) {
        notImplemented();
        return null;
    }

    /**
     * Not Implemented
     */
    public void flushBuffer() throws java.io.IOException {
        notImplemented();
    }

    /**
     * Not Implemented
     */
    public int getBufferSize() {
        notImplemented();
        return 0;
    }

    /**
     * Not Implemented
     */
    public String getCharacterEncoding() {
        notImplemented();
        return null;
    }

    /**
     * Not Implemented
     */
    public Locale getLocale() {
        notImplemented();
        return null;
    }

    public ServletOutputStream getOutputStream()
        throws IOException {
        return myOutputStream;
    }

    public String getOutputStreamContents() {
        return myOutputStream.getContents();
    }

    public PrintWriter getWriter() throws IOException {
        return new PrintWriter(myOutputStream, true);
    }

    /**
     * Not Implemented
     */
    public boolean isCommitted() {
        notImplemented();
        return false;
    }

    /**
     * Not Implemented
     */
    public void reset() {
        notImplemented();
    }

    /**
     * Not Implemented
     */
    public void resetBuffer() {
        notImplemented();
    }

    public void setExpectedError(int anErrorCode) {
        myErrorCode.setExpected(anErrorCode);
    }

    public void setExpectedError(int anErrorCode, String anErrorMessage) {
        setExpectedError(anErrorCode);
        myErrorMessage.setExpected(anErrorMessage);
    }

    public void setExpectedErrorNothing() {
        myErrorCode.setExpectNothing();
        myErrorMessage.setExpectNothing();
    }

    public void sendError(int anErrorCode) throws java.io.IOException {
        myErrorCode.setActual(anErrorCode);
    }

    public void sendError(int anErrorCode, String anErrorMessage)
        throws IOException {
        sendError(anErrorCode);
        myErrorMessage.setActual(anErrorMessage);
    }

    public void sendRedirect(String aURL) throws java.io.IOException {
        myRedirects.addActual(aURL);
    }

    /**
     * Not Implemented
     */
    public void setBufferSize(int arg1) {
        notImplemented();
    }

    public void setContentLength(int length) {
        this.length.setActual(length);
    }

    public void setExpectedContentLength(int length){
        this.length.setExpected(length);
    }

    public void setContentType(String contentType) {
        myContentTypes.addActual(contentType);
    }

    /**
     * Not Implemented
     */
    public void setDateHeader(String arg1, long arg2) {
        notImplemented();
    }

    public void setExpectedContentType(String contentType) {
        myContentTypes.addExpected(contentType);
    }

    public void setExpectedHeader(String key, String value) {
        myHeaders.addExpected(new MapEntry(key, value));
    }

    public void setExpectedRedirect(String aURL) throws IOException {
        myRedirects.addExpected(aURL);
    }

    public void setExpectedSetStatusCalls(int callCount) {
        mySetStatusCalls.setExpected(callCount);
    }

    public void setHeader(String key, String value) {
        myHeaders.addActual(new MapEntry(key, value));
    }

    /**
     * Not Implemented
     */
    public void setIntHeader(String arg1, int arg2) {
        notImplemented();
    }

    /**
     * Not Implemented
     */
    public void setLocale(Locale arg1) {
        notImplemented();
    }

    public void setStatus(int status) {
        mySetStatusCalls.inc();
    }

    /**
     * Not Implemented
     */
    public void setStatus(int arg1, String arg2) {
        notImplemented();
    }

    public void setupOutputStream(MockServletOutputStream anOutputStream) {
        myOutputStream = anOutputStream;
    }
}
