/*
 * 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.catalina.filters;

import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Locale;

import javax.servlet.ServletOutputStream;
import javax.servlet.ServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;

import org.apache.catalina.Context;
import org.apache.catalina.connector.Connector;
import org.apache.catalina.connector.Request;

/**
 * Mock HttpServletResponse
 */
public class TesterHttpServletResponse implements HttpServletResponse {

    private PrintWriter pw;
    private List<String> headerNames = new ArrayList<>();
    private List<String> headerValues = new ArrayList<>();
    private int status;

    public TesterHttpServletResponse() {
        // NOOP
    }


    @Override
    public PrintWriter getWriter() throws IOException {
        if (pw == null) {
            pw = new PrintWriter(new StringWriter());
        }
        return pw;
    }


    @Override
    public String getHeader(String name) {
        int index = headerNames.indexOf(name);
        if (index != -1) {
            return headerValues.get(index);
        }
        return null;
    }


    @Override
    public void setHeader(String name, String value) {
        int index = headerNames.indexOf(name);
        if (index != -1) {
            headerValues.set(index, value);
        } else {
            headerNames.add(name);
            headerValues.add(value);
        }
    }


    @Override
    public void addHeader(String name, String value) {
        headerNames.add(name);
        headerValues.add(value);
    }


    @Override
    public int getStatus() {
        return status;
    }


    @Override
    public void setStatus(int status) {
        this.status = status;
    }


    public void setAppCommitted(
            @SuppressWarnings("unused") boolean appCommitted) {/* NOOP */}
    public boolean isAppCommitted() { return false; }
    public Connector getConnector() { return null; }
    public void setConnector(@SuppressWarnings("unused") Connector connector) {
        // NOOP
    }
    public int getContentCount() { return -1; }
    public Context getContext() { return null; }
    public void setContext(@SuppressWarnings("unused") Context context) {
        // NOOP
    }
    public boolean getIncluded() { return false; }
    public void setIncluded(@SuppressWarnings("unused") boolean included) {
        // NOOP
    }
    public Request getRequest() { return null; }
    public void setRequest(@SuppressWarnings("unused") Request request) {
        // NOOP
    }
    public ServletResponse getResponse() { return null; }
    public OutputStream getStream() { return null; }
    public void setStream(@SuppressWarnings("unused") OutputStream stream) {
        // NOOP
    }
    public void setSuspended(@SuppressWarnings("unused") boolean suspended) {
        // NOOP
    }
    public boolean isSuspended() { return false; }
    public void setError() {/* NOOP */}
    public boolean isError() { return false; }
    /**
     * @return Always null
     * @throws IOException Never happens
     */
    public ServletOutputStream createOutputStream() throws IOException {
        return null;
    }
    /**
     * @throws IOException Never happens
     */
    public void finishResponse() throws IOException {/* NOOP */}
    public int getContentLength() { return -1; }
    @Override
    public String getContentType() { return null; }
    public PrintWriter getReporter() { return null; }
    public void recycle() {/* NOOP */}
    /**
     * @param b Unused
     * @throws IOException Never happens
     */
    public void write(int b) throws IOException {
        // NOOP
    }
    /**
     * @param b Unused
     * @throws IOException Never happens
     */
    public void write(byte b[]) throws IOException {
        // NOOP
    }
    /**
     * @param b   Unused
     * @param off Unused
     * @param len Unused
     * @throws IOException Never happens
     */
    public void write(byte b[], int off, int len) throws IOException {
        // NOOP
    }
    @Override
    public void flushBuffer() throws IOException {/* NOOP */}
    @Override
    public int getBufferSize() { return -1; }
    @Override
    public String getCharacterEncoding() { return null; }
    @Override
    public void setCharacterEncoding(String charEncoding) {/* NOOP */}
    @Override
    public ServletOutputStream getOutputStream() throws IOException {
        return null;
    }
    @Override
    public Locale getLocale() { return null; }
    @Override
    public boolean isCommitted() { return false; }
    @Override
    public void reset() {/* NOOP */}
    @Override
    public void resetBuffer() {/* NOOP */}
    @Override
    public void setBufferSize(int size) {/* NOOP */}
    @Override
    public void setContentLength(int length) {/* NOOP */}
    @Override
    public void setContentType(String type) {/* NOOP */}
    @Override
    public void setLocale(Locale locale) {/* NOOP */}
    @Override
    public Collection<String> getHeaderNames() { return null; }
    @Override
    public Collection<String> getHeaders(String name) { return Collections.emptyList(); }
    public String getMessage() { return null; }
    public void reset(@SuppressWarnings("unused") int status,
            @SuppressWarnings("unused") String message) {/* NOOP */}
    @Override
    public void addCookie(Cookie cookie) {/* NOOP */}
    @Override
    public void addDateHeader(String name, long value) {/* NOOP */}
    @Override
    public void addIntHeader(String name, int value) {/* NOOP */}
    @Override
    public boolean containsHeader(String name) { return false; }
    @Override
    public String encodeRedirectURL(String url) { return null; }
    /** @deprecated Do not use */
    @Override
    @Deprecated
    public String encodeRedirectUrl(String url) { return null; }
    @Override
    public String encodeURL(String url) { return null; }
    /** @deprecated Do not use */
    @Override
    @Deprecated
    public String encodeUrl(String url) { return null; }
    /**
     *
     * @throws IOException Never happens
     */
    public void sendAcknowledgement() throws IOException {/* NOOP */}
    @Override
    public void sendError(int status) throws IOException {/* NOOP */}
    @Override
    public void sendError(int status, String message) throws IOException {
        // NOOP
    }
    @Override
    public void sendRedirect(String location) throws IOException {/* NOOP */}
    @Override
    public void setDateHeader(String name, long value) {/* NOOP */}
    @Override
    public void setIntHeader(String name, int value) {/* NOOP */}
    /** @deprecated Do not use */
    @Override
    @Deprecated
    public void setStatus(int status, String message) {/* NOOP */}
    @Override
    public void setContentLengthLong(long length) {/* NOOP */}
}
