/*
 * 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 jakarta.servlet;

import java.io.IOException;
import java.io.PrintWriter;
import java.nio.charset.Charset;
import java.util.Locale;

/**
 * Defines an object to assist a servlet in sending a response to the client. The servlet container creates a
 * <code>ServletResponse</code> object and passes it as an argument to the servlet's <code>service</code> method.
 * <p>
 * To send binary data in a MIME body response, use the {@link ServletOutputStream} returned by
 * {@link #getOutputStream}. To send character data, use the <code>PrintWriter</code> object returned by
 * {@link #getWriter}. To mix binary and text data, for example, to create a multipart response, use a
 * <code>ServletOutputStream</code> and manage the character sections manually.
 * <p>
 * The charset for the MIME body response can be specified explicitly or implicitly. The priority order for specifying
 * the response body is:
 * <ol>
 * <li>explicitly per request using {@link #setCharacterEncoding} and {@link #setContentType}</li>
 * <li>implicitly per request using {@link #setLocale}</li>
 * <li>per web application via the deployment descriptor or
 * {@link ServletContext#setRequestCharacterEncoding(String)}</li>
 * <li>container default via vendor specific configuration</li>
 * <li>ISO-8859-1</li>
 * </ol>
 * The <code>setCharacterEncoding</code>, <code>setContentType</code>, or <code>setLocale</code> method must be called
 * before <code>getWriter</code> and before committing the response for the character encoding to be used.
 * <p>
 * See the Internet RFCs such as <a href="http://www.ietf.org/rfc/rfc2045.txt"> RFC 2045</a> for more information on
 * MIME. Protocols such as SMTP and HTTP define profiles of MIME, and those standards are still evolving.
 *
 * @see ServletOutputStream
 */
public interface ServletResponse {

    /**
     * Returns the name of the character encoding (MIME charset) used for the body sent in this response. The charset
     * for the MIME body response can be specified explicitly or implicitly. The priority order for specifying the
     * response body is:
     * <ol>
     * <li>explicitly per request using {@link #setCharacterEncoding} and {@link #setContentType}</li>
     * <li>implicitly per request using {@link #setLocale}</li>
     * <li>per web application via the deployment descriptor or
     * {@link ServletContext#setRequestCharacterEncoding(String)}</li>
     * <li>container default via vendor specific configuration</li>
     * <li>ISO-8859-1</li>
     * </ol>
     * Calls made to {@link #setCharacterEncoding}, {@link #setContentType} or {@link #setLocale} after
     * <code>getWriter</code> has been called or after the response has been committed have no effect on the character
     * encoding. If no character encoding has been specified, <code>ISO-8859-1</code> is returned.
     * <p>
     * See <a href="http://www.ietf.org/rfc/rfc2047.txt">RFC 2047</a> for more information about character encoding and
     * MIME.
     *
     * @return a <code>String</code> specifying the name of the character encoding, for example, <code>UTF-8</code>
     */
    String getCharacterEncoding();

    /**
     * Returns the content type used for the MIME body sent in this response. The content type proper must have been
     * specified using {@link #setContentType} before the response is committed. If no content type has been specified,
     * this method returns null. If a content type has been specified and a character encoding has been explicitly or
     * implicitly specified as described in {@link #getCharacterEncoding}, the charset parameter is included in the
     * string returned. If no character encoding has been specified, the charset parameter is omitted.
     *
     * @return a <code>String</code> specifying the content type, for example, <code>text/html; charset=UTF-8</code>, or
     *             null
     *
     * @since Servlet 2.4
     */
    String getContentType();

    /**
     * Returns a {@link ServletOutputStream} suitable for writing binary data in the response. The servlet container
     * does not encode the binary data.
     * <p>
     * Calling flush() on the ServletOutputStream commits the response. Either this method or {@link #getWriter} may be
     * called to write the body, not both.
     *
     * @return a {@link ServletOutputStream} for writing binary data
     *
     * @exception IllegalStateException if the <code>getWriter</code> method has been called on this response
     * @exception IOException           if an input or output exception occurred
     *
     * @see #getWriter
     */
    ServletOutputStream getOutputStream() throws IOException;

    /**
     * Returns a <code>PrintWriter</code> object that can send character text to the client. The
     * <code>PrintWriter</code> uses the character encoding returned by {@link #getCharacterEncoding}. If the response's
     * character encoding has not been specified as described in <code>getCharacterEncoding</code> (i.e., the method
     * just returns the default value <code>ISO-8859-1</code>), <code>getWriter</code> updates it to
     * <code>ISO-8859-1</code>.
     * <p>
     * Calling flush() on the <code>PrintWriter</code> commits the response.
     * <p>
     * Either this method or {@link #getOutputStream} may be called to write the body, not both.
     *
     * @return a <code>PrintWriter</code> object that can return character data to the client
     *
     * @exception java.io.UnsupportedEncodingException if the character encoding returned by
     *                                                     <code>getCharacterEncoding</code> cannot be used
     * @exception IllegalStateException                if the <code>getOutputStream</code> method has already been
     *                                                     called for this response object
     * @exception IOException                          if an input or output exception occurred
     *
     * @see #getOutputStream
     * @see #setCharacterEncoding
     */
    PrintWriter getWriter() throws IOException;

    /**
     * Sets the character encoding (MIME charset) of the response being sent to the client, for example, to UTF-8. If
     * the character encoding has already been set by container default, ServletContext default,
     * {@link #setCharacterEncoding(Charset)}, {@link #setContentType} or {@link #setLocale}, this method overrides it.
     * Calling {@link #setContentType} with the <code>String</code> of <code>text/html</code> and calling this method
     * with the <code>String</code> of <code>UTF-8</code> is equivalent with calling <code>setContentType</code> with
     * the <code>String</code> of <code>text/html; charset=UTF-8</code>.
     * <p>
     * This method can be called repeatedly to change the character encoding. This method has no effect if it is called
     * after <code>getWriter</code> has been called or after the response has been committed.
     * <p>
     * Containers must communicate the character encoding used for the servlet response's writer to the client if the
     * protocol provides a way for doing so. In the case of HTTP, the character encoding is communicated as part of the
     * <code>Content-Type</code> header for text media types. Note that the character encoding cannot be communicated
     * via HTTP headers if the servlet does not specify a content type; however, it is still used to encode text written
     * via the servlet response's writer.
     *
     * @param charset a String specifying only the character set defined by
     *                    <a href="http://www.iana.org/assignments/character-sets">IANA Character Sets</a>
     *
     * @see #setContentType #setLocale
     * @see #setCharacterEncoding(Charset)
     *
     * @since Servlet 2.4
     */
    void setCharacterEncoding(String charset);

    /**
     * Sets the character encoding (MIME charset) of the response being sent to the client, for example, to UTF-8. If
     * the character encoding has already been set by container default, ServletContext default,
     * {@link #setCharacterEncoding(String)}, {@link #setContentType} or {@link #setLocale}, this method overrides it.
     * Calling {@link #setContentType} with the <code>String</code> of <code>text/html</code> and calling this method
     * with the <code>StandardCharsets.UTF-8</code> is equivalent with calling <code>setContentType</code> with the
     * <code>String</code> of <code>text/html; charset=UTF-8</code>.
     * <p>
     * This method can be called repeatedly to change the character encoding. This method has no effect if it is called
     * after <code>getWriter</code> has been called or after the response has been committed.
     * <p>
     * Containers must communicate the character encoding used for the servlet response's writer to the client if the
     * protocol provides a way for doing so. In the case of HTTP, the character encoding is communicated as part of the
     * <code>Content-Type</code> header for text media types. Note that the character encoding cannot be communicated
     * via HTTP headers if the servlet does not specify a content type; however, it is still used to encode text written
     * via the servlet response's writer.
     *
     * @param encoding The encoding to use or {@code null}
     *
     * @see #setContentType #setLocale
     * @see #setCharacterEncoding(String)
     *
     * @since Servlet 6.1
     */
    default void setCharacterEncoding(Charset encoding) {
        if (encoding == null) {
            setCharacterEncoding((String) null);
        } else {
            setCharacterEncoding(encoding.name());
        }
    }

    /**
     * Sets the length of the content body in the response In HTTP servlets, this method sets the HTTP Content-Length
     * header.
     *
     * @param len an integer specifying the length of the content being returned to the client; sets the Content-Length
     *                header
     */
    void setContentLength(int len);

    /**
     * Sets the length of the content body in the response In HTTP servlets, this method sets the HTTP Content-Length
     * header.
     *
     * @param length an integer specifying the length of the content being returned to the client; sets the
     *                   Content-Length header
     *
     * @since Servlet 3.1
     */
    void setContentLengthLong(long length);

    /**
     * Sets the content type of the response being sent to the client, if the response has not been committed yet. The
     * given content type may include a character encoding specification, for example,
     * <code>text/html;charset=UTF-8</code>. The response's character encoding is only set from the given content type
     * if this method is called before <code>getWriter</code> is called.
     * <p>
     * This method may be called repeatedly to change content type and character encoding. This method has no effect if
     * called after the response has been committed. It does not set the response's character encoding if it is called
     * after <code>getWriter</code> has been called or after the response has been committed.
     * <p>
     * Containers must communicate the content type and the character encoding used for the servlet response's writer to
     * the client if the protocol provides a way for doing so. In the case of HTTP, the <code>Content-Type</code> header
     * is used.
     *
     * @param type a <code>String</code> specifying the MIME type of the content
     *
     * @see #setLocale
     * @see #setCharacterEncoding
     * @see #getOutputStream
     * @see #getWriter
     */
    void setContentType(String type);

    /**
     * Sets the preferred buffer size for the body of the response. The servlet container will use a buffer at least as
     * large as the size requested. The actual buffer size used can be found using <code>getBufferSize</code>.
     * <p>
     * A larger buffer allows more content to be written before anything is actually sent, thus providing the servlet
     * with more time to set appropriate status codes and headers. A smaller buffer decreases server memory load and
     * allows the client to start receiving data more quickly.
     * <p>
     * This method must be called before any response body content is written; if content has been written or the
     * response object has been committed, this method throws an <code>IllegalStateException</code>.
     *
     * @param size the preferred buffer size
     *
     * @exception IllegalStateException if this method is called after content has been written
     *
     * @see #getBufferSize
     * @see #flushBuffer
     * @see #isCommitted
     * @see #reset
     */
    void setBufferSize(int size);

    /**
     * Returns the actual buffer size used for the response. If no buffering is used, this method returns 0.
     *
     * @return the actual buffer size used
     *
     * @see #setBufferSize
     * @see #flushBuffer
     * @see #isCommitted
     * @see #reset
     */
    int getBufferSize();

    /**
     * Forces any content in the buffer to be written to the client. A call to this method automatically commits the
     * response, meaning the status code and headers will be written.
     *
     * @throws IOException if an I/O occurs during the flushing of the response
     *
     * @see #setBufferSize
     * @see #getBufferSize
     * @see #isCommitted
     * @see #reset
     */
    void flushBuffer() throws IOException;

    /**
     * Clears the content of the underlying buffer in the response without clearing headers or status code. If the
     * response has been committed, this method throws an <code>IllegalStateException</code>.
     *
     * @see #setBufferSize
     * @see #getBufferSize
     * @see #isCommitted
     * @see #reset
     *
     * @since Servlet 2.3
     */
    void resetBuffer();

    /**
     * Returns a boolean indicating if the response has been committed. A committed response has already had its status
     * code and headers written.
     *
     * @return a boolean indicating if the response has been committed
     *
     * @see #setBufferSize
     * @see #getBufferSize
     * @see #flushBuffer
     * @see #reset
     */
    boolean isCommitted();

    /**
     * Clears any data that exists in the buffer as well as the status code and headers. If the response has been
     * committed, this method throws an <code>IllegalStateException</code>.
     *
     * @exception IllegalStateException if the response has already been committed
     *
     * @see #setBufferSize
     * @see #getBufferSize
     * @see #flushBuffer
     * @see #isCommitted
     */
    void reset();

    /**
     * Sets the locale of the response, if the response has not been committed yet. It also sets the response's
     * character encoding appropriately for the locale, if the character encoding has not been explicitly set using
     * {@link #setContentType}, {@link #setCharacterEncoding(String)} or {@link #setCharacterEncoding(Charset)},
     * <code>getWriter</code> hasn't been called yet, and the response hasn't been committed yet. If the deployment
     * descriptor contains a <code>locale-encoding-mapping-list</code> element, and that element provides a mapping for
     * the given locale, that mapping is used. Otherwise, the mapping from locale to character encoding is container
     * dependent.
     * <p>
     * This method may be called repeatedly to change locale and character encoding. The method has no effect if called
     * after the response has been committed. It does not set the response's character encoding if it is called after
     * {@link #setContentType} has been called with a charset specification, after {@link #setCharacterEncoding} has
     * been called, after <code>getWriter</code> has been called, or after the response has been committed.
     * <p>
     * Containers must communicate the locale and the character encoding used for the servlet response's writer to the
     * client if the protocol provides a way for doing so. In the case of HTTP, the locale is communicated via the
     * <code>Content-Language</code> header, the character encoding as part of the <code>Content-Type</code> header for
     * text media types. Note that the character encoding cannot be communicated via HTTP headers if the servlet does
     * not specify a content type; however, it is still used to encode text written via the servlet response's writer.
     *
     * @param loc the locale of the response
     *
     * @see #getLocale
     * @see #setContentType
     * @see #setCharacterEncoding(String)
     * @see #setCharacterEncoding(Charset)
     */
    void setLocale(Locale loc);

    /**
     * Returns the locale specified for this response using the {@link #setLocale} method. Calls made to
     * <code>setLocale</code> after the response is committed have no effect.
     *
     * @return The locale specified for this response using the {@link #setLocale} method. If no locale has been
     *             specified, the container's default locale is returned.
     *
     * @see #setLocale
     */
    Locale getLocale();

}
