/*
 * 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.sling.servlethelpers;

import java.io.PrintWriter;
import java.util.Collection;
import java.util.Locale;

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

import org.apache.commons.lang3.StringUtils;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.adapter.SlingAdaptable;
import org.osgi.annotation.versioning.ConsumerType;

/**
 * Mock {@link SlingHttpServletResponse} implementation.
 */
@ConsumerType
public class MockSlingHttpServletResponse extends SlingAdaptable implements SlingHttpServletResponse {

    static final String CHARSET_SEPARATOR = ";charset=";

    private boolean enableCheckForClosedWriter = false;

    private String contentType;
    private String characterEncoding;
    private int contentLength;
    private int status = HttpServletResponse.SC_OK;
    private String statusMessage;
    private int bufferSize = 1024 * 8;
    private boolean isCommitted;
    private Locale locale = Locale.US;
    private final HeaderSupport headerSupport = new HeaderSupport();
    private final ResponseBodySupport bodySupport = new ResponseBodySupport();
    private final CookieSupport cookieSupport = new CookieSupport();

    public void setEnableCheckForClosedWriter(boolean enableCheckForClosedWriter) {
        bodySupport.setEnableCheckForClosedWriter(enableCheckForClosedWriter);
    }

    @Override
    public String getContentType() {
        if (this.contentType == null) {
            return null;
        } else {
            return this.contentType
                    + (StringUtils.isNotBlank(characterEncoding) ? CHARSET_SEPARATOR + characterEncoding : "");
        }
    }

    @Override
    public void setContentType(String type) {
        this.contentType = type;
        if (StringUtils.contains(this.contentType, CHARSET_SEPARATOR)) {
            this.characterEncoding = StringUtils.substringAfter(this.contentType, CHARSET_SEPARATOR);
            this.contentType = StringUtils.substringBefore(this.contentType, CHARSET_SEPARATOR);
        }
    }

    @Override
    public void setCharacterEncoding(String charset) {
        this.characterEncoding = charset;
    }

    @Override
    public String getCharacterEncoding() {
        return this.characterEncoding;
    }

    @Override
    public void setContentLength(int len) {
        this.contentLength = len;
    }

    public int getContentLength() {
        return this.contentLength;
    }

    @Override
    public void setStatus(int sc, String sm) {
        setStatus(sc);
        this.statusMessage = sm;
    }

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

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

    @Override
    public void sendError(int sc, String msg) {
        setStatus(sc);
        this.statusMessage = msg;
    }

    @Override
    public void sendError(int sc) {
        setStatus(sc);
    }

    @Override
    public void sendRedirect(String location) {
        setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
        setHeader("Location", location);
    }

    @Override
    public void addHeader(String name, String value) {
        headerSupport.addHeader(name, value);
    }

    @Override
    public void addIntHeader(String name, int value) {
        headerSupport.addIntHeader(name, value);
    }

    @Override
    public void addDateHeader(String name, long date) {
        headerSupport.addDateHeader(name, date);
    }

    @Override
    public void setHeader(String name, String value) {
        headerSupport.setHeader(name, value);
    }

    @Override
    public void setIntHeader(String name, int value) {
        headerSupport.setIntHeader(name, value);
    }

    @Override
    public void setDateHeader(String name, long date) {
        headerSupport.setDateHeader(name, date);
    }

    @Override
    public boolean containsHeader(String name) {
        return headerSupport.containsHeader(name);
    }

    @Override
    public String getHeader(String name) {
        return headerSupport.getHeader(name);
    }

    @Override
    public Collection<String> getHeaders(String name) {
        return headerSupport.getHeaders(name);
    }

    @Override
    public Collection<String> getHeaderNames() {
        return headerSupport.getHeaderNames();
    }

    @Override
    public PrintWriter getWriter() {
        return bodySupport.getWriter(getCharacterEncoding());
    }

    @Override
    public ServletOutputStream getOutputStream() {
        return bodySupport.getOutputStream();
    }

    @Override
    public void reset() {
        if (isCommitted()) {
            throw new IllegalStateException("Response already committed.");
        }
        bodySupport.reset();
        headerSupport.reset();
        cookieSupport.reset();
        status = HttpServletResponse.SC_OK;
        contentLength = 0;
    }

    @Override
    public void resetBuffer() {
        if (isCommitted()) {
            throw new IllegalStateException("Response already committed.");
        }
        bodySupport.reset();
    }

    @Override
    public int getBufferSize() {
        return this.bufferSize;
    }

    @Override
    public void setBufferSize(int size) {
        this.bufferSize = size;
    }

    @Override
    public void flushBuffer() {
        isCommitted = true;
    }

    @Override
    public boolean isCommitted() {
        return isCommitted;
    }

    public byte[] getOutput() {
        return bodySupport.getOutput();
    }

    public String getOutputAsString() {
        return bodySupport.getOutputAsString(getCharacterEncoding());
    }

    @Override
    public void addCookie(Cookie cookie) {
        cookieSupport.addCookie(cookie);
    }

    /**
     * Get cookie
     * @param name Cookie name
     * @return Cookie or null
     */
    public Cookie getCookie(String name) {
        return cookieSupport.getCookie(name);
    }

    /**
     * Get cookies
     * @return Cookies array or null if no cookie defined
     */
    public Cookie[] getCookies() {
        return cookieSupport.getCookies();
    }

    @Override
    public Locale getLocale() {
        return locale;
    }

    @Override
    public void setLocale(Locale loc) {
        this.locale = loc;
    }

    /**
     * @return status message that was set using {@link #setStatus(int, String)} or {@link #sendError(int, String)}
     */
    public String getStatusMessage() {
        return statusMessage;
    }
    
    /**
     * @deprecated As of package version 1.6, use {@link #getStatusMessage()} instead.
     * 
     * @return status message that was set using {@link #setStatus(int, String)} or {@link #sendError(int, String)}
     */
    @Deprecated
    public String geStatusMessage() {
        return this.getStatusMessage();
    }

    @Override
    public <AdapterType> AdapterType adaptTo(Class<AdapterType> type) {
        return AdaptableUtil.adaptToWithoutCaching(this, type);
    }

    // --- unsupported operations ---
    @Override
    public String encodeRedirectUrl(String url) {
        throw new UnsupportedOperationException();
    }

    @Override
    public String encodeRedirectURL(String url) {
        throw new UnsupportedOperationException();
    }

    @Override
    public String encodeUrl(String url) {
        throw new UnsupportedOperationException();
    }

    @Override
    public String encodeURL(String url) {
        throw new UnsupportedOperationException();
    }

    @Override
    public void setContentLengthLong(long len) {
        throw new UnsupportedOperationException();
    }

}
