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

import java.io.IOException;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Supplier;

import jakarta.servlet.WriteListener;

import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
import org.apache.tomcat.util.buf.CharsetHolder;
import org.apache.tomcat.util.buf.MessageBytes;
import org.apache.tomcat.util.http.MimeHeaders;
import org.apache.tomcat.util.http.parser.MediaType;
import org.apache.tomcat.util.res.StringManager;

/**
 * Response object.
 */
public final class Response {
    /**
     * Default constructor.
     */
    public Response() {
    }

    private static final StringManager sm = StringManager.getManager(Response.class);
    private static final Log log = LogFactory.getLog(Response.class);


    // ----------------------------------------------------- Class Variables

    /**
     * Default locale as mandated by the spec.
     */
    private static final Locale DEFAULT_LOCALE = Locale.getDefault();


    // ----------------------------------------------------- Instance Variables

    /**
     * Status code.
     */
    int status = 200;


    /**
     * Status message.
     */
    String message = null;


    /**
     * Response headers.
     */
    final MimeHeaders headers = new MimeHeaders();


    private Supplier<Map<String,String>> trailerFieldsSupplier = null;

    /**
     * Associated output buffer.
     */
    OutputBuffer outputBuffer;


    /**
     * Notes.
     */
    final Object[] notes = new Object[Constants.MAX_NOTES];


    /**
     * Committed flag.
     */
    volatile boolean committed = false;


    /**
     * Action hook.
     */
    volatile ActionHook hook;


    /**
     * HTTP specific fields.
     */
    String contentType = null;
    String contentLanguage = null;
    private CharsetHolder charsetHolder = CharsetHolder.EMPTY;
    long contentLength = -1;
    private Locale locale = DEFAULT_LOCALE;

    // General information
    private long contentWritten = 0;
    private long commitTimeNanos = -1;

    /**
     * Holds response writing error exception.
     */
    private Exception errorException = null;

    /**
     * With the introduction of async processing and the possibility of non-container threads calling sendError()
     * tracking the current error state and ensuring that the correct error page is called becomes more complicated.
     * This state attribute helps by tracking the current error state and informing callers that attempt to change state
     * if the change was successful or if another thread got there first.
     *
     * <pre>
     * The state machine is very simple:
     *
     * 0 - NONE
     * 1 - NOT_REPORTED
     * 2 - REPORTED
     *
     *
     *   -->---->-- >NONE
     *   |   |        |
     *   |   |        | setError()
     *   ^   ^        |
     *   |   |       \|/
     *   |   |-<-NOT_REPORTED
     *   |            |
     *   ^            | report()
     *   |            |
     *   |           \|/
     *   |----<----REPORTED
     * </pre>
     */
    private final AtomicInteger errorState = new AtomicInteger(0);

    Request req;


    // ------------------------------------------------------------- Properties

    /**
     * Get the associated request.
     *
     * @return The associated request
     */
    public Request getRequest() {
        return req;
    }

    /**
     * Set the associated request.
     *
     * @param req The associated request
     */
    public void setRequest(Request req) {
        this.req = req;
    }


    /**
     * Set the output buffer.
     *
     * @param outputBuffer The output buffer
     */
    public void setOutputBuffer(OutputBuffer outputBuffer) {
        this.outputBuffer = outputBuffer;
    }


    /**
     * Get the response headers.
     *
     * @return The response headers
     */
    public MimeHeaders getMimeHeaders() {
        return headers;
    }


    void setHook(ActionHook hook) {
        this.hook = hook;
    }


    // -------------------- Per-Response "notes" --------------------

    /**
     * Set a note at the given position.
     *
     * @param pos The position
     * @param value The value to set
     */
    public void setNote(int pos, Object value) {
        notes[pos] = value;
    }


    /**
     * Get the note at the given position.
     *
     * @param pos The position
     * @return The note value
     */
    public Object getNote(int pos) {
        return notes[pos];
    }


    // -------------------- Actions --------------------

    /**
     * Perform an action on this response.
     *
     * @param actionCode The action code
     * @param param The action parameter
     */
    public void action(ActionCode actionCode, Object param) {
        if (hook != null) {
            hook.action(actionCode, Objects.requireNonNullElse(param, this));
        }
    }


    // -------------------- State --------------------

    /**
     * Get the response status code.
     *
     * @return The response status code
     */
    public int getStatus() {
        return status;
    }


    /**
     * Set the response status.
     *
     * @param status The status value to set
     */
    public void setStatus(int status) {
        this.status = status;
    }


    /**
     * Get the status message.
     *
     * @return The message associated with the current status
     */
    public String getMessage() {
        return message;
    }


    /**
     * Set the status message.
     *
     * @param message The status message to set
     */
    public void setMessage(String message) {
        this.message = message;
    }


    /**
     * Check if the response has been committed.
     *
     * @return {@code true} if the response has been committed
     */
    public boolean isCommitted() {
        return committed;
    }


    /**
     * Set the committed flag.
     *
     * @param v The committed flag value
     */
    public void setCommitted(boolean v) {
        if (v && !this.committed) {
            this.commitTimeNanos = System.nanoTime();
        }
        this.committed = v;
    }

    /**
     * Return the time the response was committed (based on System.currentTimeMillis).
     *
     * @return the time the response was committed
     */
    public long getCommitTime() {
        return System.currentTimeMillis() - TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - commitTimeNanos);
    }

    /**
     * Return the time the response was committed (based on System.nanoTime).
     *
     * @return the time the response was committed
     */
    public long getCommitTimeNanos() {
        return commitTimeNanos;
    }

    // -----------------Error State --------------------

    /**
     * Set the error Exception that occurred during the writing of the response processing.
     *
     * @param ex The exception that occurred
     */
    public void setErrorException(Exception ex) {
        if (errorException == null) {
            errorException = ex;
        }
    }


    /**
     * Get the Exception that occurred during the writing of the response.
     *
     * @return The exception that occurred
     */
    public Exception getErrorException() {
        return errorException;
    }


    /**
     * Check if an exception has occurred during response writing.
     *
     * @return {@code true} if an exception has occurred
     */
    public boolean isExceptionPresent() {
        return errorException != null;
    }


    /**
     * Set the error flag if not already set.
     */
    public void setError() {
        errorState.compareAndSet(0, 1);
    }


    /**
     * Error flag accessor.
     *
     * @return <code>true</code> if the response has encountered an error
     */
    public boolean isError() {
        return errorState.get() > 0;
    }


    /**
     * Check if error report is required.
     *
     * @return {@code true} if error report is required
     */
    public boolean isErrorReportRequired() {
        return errorState.get() == 1;
    }


    /**
     * Set the error as reported.
     *
     * @return {@code true} if the error state was successfully transitioned to reported
     */
    public boolean setErrorReported() {
        return errorState.compareAndSet(1, 2);
    }


    /**
     * Reset the error state.
     */
    public void resetError() {
        errorState.set(0);
    }


    // -------------------- Methods --------------------

    /**
     * Reset the response to its initial state.
     *
     * @throws IllegalStateException if the response has already been committed
     */
    public void reset() throws IllegalStateException {

        if (committed) {
            throw new IllegalStateException();
        }

        recycle(false);
    }


    // -------------------- Headers --------------------
    /**
     * Does the response contain the given header. <br>
     * Warning: This method always returns <code>false</code> for Content-Type and Content-Length.
     *
     * @param name The name of the header of interest
     *
     * @return {@code true} if the response contains the header.
     */
    public boolean containsHeader(String name) {
        return headers.getHeader(name) != null;
    }


    /**
     * Set a response header.
     *
     * @param name The header name
     * @param value The header value
     */
    public void setHeader(String name, String value) {
        char cc = name.charAt(0);
        if (cc == 'C' || cc == 'c') {
            if (checkSpecialHeader(name, value)) {
                return;
            }
        }
        if (value == null) {
            headers.removeHeader(name);
        } else {
            headers.setValue(name).setString(value);
        }
    }


    /**
     * Add a response header with the given name and value.
     *
     * @param name The header name
     * @param value The header value
     */
    public void addHeader(String name, String value) {
        addHeader(name, value, null);
    }


    /**
     * Add a response header with the given name, value, and charset.
     *
     * @param name The header name
     * @param value The header value
     * @param charset The charset for the header value
     */
    public void addHeader(String name, String value, Charset charset) {
        char cc = name.charAt(0);
        if (cc == 'C' || cc == 'c') {
            if (checkSpecialHeader(name, value)) {
                return;
            }
        }
        MessageBytes mb = headers.addValue(name);
        if (charset != null) {
            mb.setCharset(charset);
        }
        mb.setString(value);
    }


    /**
     * Set the trailer fields supplier.
     *
     * @param supplier The trailer fields supplier
     */
    public void setTrailerFields(Supplier<Map<String,String>> supplier) {
        AtomicBoolean trailerFieldsSupported = new AtomicBoolean(false);
        action(ActionCode.IS_TRAILER_FIELDS_SUPPORTED, trailerFieldsSupported);
        if (!trailerFieldsSupported.get()) {
            throw new IllegalStateException(sm.getString("response.noTrailers.notSupported"));
        }

        this.trailerFieldsSupplier = supplier;
    }


    /**
     * Get the trailer fields supplier.
     *
     * @return The trailer fields supplier
     */
    public Supplier<Map<String,String>> getTrailerFields() {
        return trailerFieldsSupplier;
    }


    /**
     * Set internal fields for special header names. Called from set/addHeader. Return true if the header is special, no
     * need to set the header.
     */
    private boolean checkSpecialHeader(String name, String value) {
        if (name.equalsIgnoreCase("Content-Type")) {
            setContentType(value);
            return true;
        }
        if (name.equalsIgnoreCase("Content-Length")) {
            try {
                if (value == null) {
                    setContentLength(-1);
                    return true;
                }
                long cL = Long.parseLong(value);
                setContentLength(cL);
            } catch (NumberFormatException ex) {
                setContentLength(-1);
                log.warn(sm.getString("response.contentlength.invalid", value), ex);
            }
            return true;
        }
        return false;
    }


    /**
     * Signal that we're done with the headers, and body will follow.
     */
    public void commit() {
        action(ActionCode.COMMIT, this);
        setCommitted(true);
    }


    // -------------------- I18N --------------------


    /**
     * Get the locale for this response.
     *
     * @return The locale for this response
     */
    public Locale getLocale() {
        return locale;
    }

    /**
     * Called explicitly by user to set the Content-Language and the default encoding.
     *
     * @param locale The locale to use for this response
     */
    public void setLocale(Locale locale) {

        if (locale == null) {
            this.locale = null;
            this.contentLanguage = null;
            return;
        }

        // Save the locale for use by getLocale()
        this.locale = locale;

        // Set the contentLanguage for header output
        contentLanguage = locale.toLanguageTag();
    }

    /**
     * Return the content language.
     *
     * @return The language code for the language currently associated with this response
     */
    public String getContentLanguage() {
        return contentLanguage;
    }


    /**
     * Get the charset holder.
     *
     * @return The charset holder
     */
    public CharsetHolder getCharsetHolder() {
        return charsetHolder;
    }


    /**
     * Set the charset holder.
     *
     * @param charsetHolder The charset holder
     */
    public void setCharsetHolder(CharsetHolder charsetHolder) {
        this.charsetHolder = charsetHolder;
    }


    /**
     * Sets the content type. This method must preserve any response charset that may already have been set via a call
     * to response.setContentType(), response.setLocale(), or response.setCharacterEncoding().
     *
     * @param type the content type
     */
    public void setContentType(String type) {

        if (type == null) {
            this.contentType = null;
            return;
        }

        MediaType m = null;
        try {
            m = MediaType.parseMediaType(new StringReader(type));
        } catch (IOException ignore) {
            // Ignore - null test below handles this
        }
        if (m == null) {
            // Invalid - Assume no charset and just pass through whatever
            // the user provided.
            this.contentType = type;
            return;
        }

        String charsetValue = m.getCharset();

        if (charsetValue == null) {
            // No charset and we know value is valid as parser was successful
            // Pass-through user provided value in case user-agent is buggy and
            // requires specific format
            this.contentType = type;
        } else {
            // There is a charset so have to rebuild content-type without it
            this.contentType = m.toStringNoCharset();
            charsetValue = charsetValue.trim();
            if (!charsetValue.isEmpty()) {
                charsetHolder = CharsetHolder.getInstance(charsetValue);
                try {
                    charsetHolder.validate();
                } catch (UnsupportedEncodingException e) {
                    log.warn(sm.getString("response.encoding.invalid", charsetValue), e);
                }
            }
        }
    }

    /**
     * Set the content type without charset.
     *
     * @param type The content type
     */
    public void setContentTypeNoCharset(String type) {
        this.contentType = type;
    }

    /**
     * Get the content type.
     *
     * @return The content type, including charset if set
     */
    public String getContentType() {

        String ret = contentType;
        if (ret != null) {
            String charsetName = charsetHolder.getName();
            if (charsetName != null) {
                ret = ret + ";charset=" + charsetName;
            }
        }

        return ret;
    }

    /**
     * Set the content length.
     *
     * @param contentLength The content length
     */
    public void setContentLength(long contentLength) {
        this.contentLength = contentLength;
    }

    /**
     * Get the content length as an int.
     *
     * @return The content length as an int, or -1 if the length exceeds Integer.MAX_VALUE
     */
    public int getContentLength() {
        long length = getContentLengthLong();

        if (length < Integer.MAX_VALUE) {
            return (int) length;
        }
        return -1;
    }

    /**
     * Get the content length as a long.
     *
     * @return The content length
     */
    public long getContentLengthLong() {
        return contentLength;
    }


    /**
     * Write a chunk of bytes.
     *
     * @param chunk The ByteBuffer to write
     *
     * @throws IOException If an I/O error occurs during the write
     */
    public void doWrite(ByteBuffer chunk) throws IOException {
        int len = chunk.remaining();
        outputBuffer.doWrite(chunk);
        contentWritten += len - chunk.remaining();
    }


    /**
     * Recycle this response.
     */
    public void recycle() {
        recycle(true);
    }


    private void recycle(boolean responseComplete) {
        contentType = null;
        contentLanguage = null;
        locale = DEFAULT_LOCALE;
        charsetHolder = CharsetHolder.EMPTY;
        contentLength = -1;
        status = 200;
        message = null;
        committed = false;
        commitTimeNanos = -1;
        errorException = null;
        resetError();
        headers.recycle();
        trailerFieldsSupplier = null;
        // Servlet 3.1 non-blocking write listener
        listener = null;
        synchronized (nonBlockingStateLock) {
            fireListener = false;
            registeredForWrite = false;
        }

        // update counters
        contentWritten = 0;

        if (responseComplete && hook instanceof NonPipeliningProcessor) {
            /*
             * No requirement to maintain state between responses so clear the hook (a.k.a. Processor) and the output
             * buffer to aid GC.
             *
             * Only clear these between responses. They need to be retained when the response is reset.
             */
            setHook(null);
            setOutputBuffer(null);
        }
    }


    /**
     * Bytes written by application - i.e. before compression, chunking, etc.
     *
     * @return The total number of bytes written to the response by the application. This will not be the number of
     *             bytes written to the network which may be more or less than this value.
     */
    public long getContentWritten() {
        return contentWritten;
    }

    /**
     * Bytes written to socket - i.e. after compression, chunking, etc.
     *
     * @param flush Should any remaining bytes be flushed before returning the total? If {@code false} bytes remaining
     *                  in the buffer will not be included in the returned value
     *
     * @return The total number of bytes written to the socket for this response
     */
    public long getBytesWritten(boolean flush) {
        if (flush) {
            action(ActionCode.CLIENT_FLUSH, this);
        }
        return outputBuffer.getBytesWritten();
    }

    /*
     * State for non-blocking output is maintained here as it is the one point easily reachable from the
     * CoyoteOutputStream and the Processor which both need access to state.
     */
    volatile WriteListener listener;
    // Ensures listener is only fired after a call is isReady()
    private boolean fireListener = false;
    // Tracks write registration to prevent duplicate registrations
    private boolean registeredForWrite = false;
    // Lock used to manage concurrent access to above flags
    private final Object nonBlockingStateLock = new Object();

    /**
     * Get the write listener.
     *
     * @return The write listener
     */
    public WriteListener getWriteListener() {
        return listener;
    }

    /**
     * Set the write listener.
     *
     * @param listener The write listener
     */
    public void setWriteListener(WriteListener listener) {
        if (listener == null) {
            throw new NullPointerException(sm.getString("response.nullWriteListener"));
        }
        if (getWriteListener() != null) {
            throw new IllegalStateException(sm.getString("response.writeListenerSet"));
        }
        // Note: This class is not used for HTTP upgrade so only need to test
        // for async
        AtomicBoolean result = new AtomicBoolean(false);
        action(ActionCode.ASYNC_IS_ASYNC, result);
        if (!result.get()) {
            throw new IllegalStateException(sm.getString("response.notAsync"));
        }

        this.listener = listener;

        // The container is responsible for the first call to
        // listener.onWritePossible(). If isReady() returns true, the container
        // needs to call listener.onWritePossible() from a new thread. If
        // isReady() returns false, the socket will be registered for write and
        // the container will call listener.onWritePossible() once data can be
        // written.
        if (isReady()) {
            synchronized (nonBlockingStateLock) {
                // Ensure we don't get multiple write registrations if
                // ServletOutputStream.isReady() returns false during a call to
                // onDataAvailable()
                registeredForWrite = true;
                // Need to set the fireListener flag otherwise when the
                // container tries to trigger onWritePossible, nothing will
                // happen
                fireListener = true;
            }
            action(ActionCode.DISPATCH_WRITE, null);
            if (!req.isRequestThread()) {
                // Not on a container thread so need to execute the dispatch
                action(ActionCode.DISPATCH_EXECUTE, null);
            }
        }
    }

    /**
     * Check if the response is ready for writing.
     *
     * @return {@code true} if ready for writing
     */
    public boolean isReady() {
        if (listener == null) {
            return true;
        }
        // Assume write is not possible
        boolean ready;
        synchronized (nonBlockingStateLock) {
            if (registeredForWrite) {
                fireListener = true;
                return false;
            }
            ready = checkRegisterForWrite();
            fireListener = !ready;
        }
        return ready;
    }

    /**
     * Check and register for write interest.
     *
     * @return {@code true} if ready for write
     */
    public boolean checkRegisterForWrite() {
        AtomicBoolean ready = new AtomicBoolean(false);
        synchronized (nonBlockingStateLock) {
            if (!registeredForWrite) {
                action(ActionCode.NB_WRITE_INTEREST, ready);
                registeredForWrite = !ready.get();
            }
        }
        return ready.get();
    }

    /**
     * Called when writing is possible.
     *
     * @throws IOException If an I/O error occurs
     */
    public void onWritePossible() throws IOException {
        // Any buffered data left over from a previous non-blocking write is
        // written in the Processor so if this point is reached the app is able
        // to write data.
        boolean fire = false;
        synchronized (nonBlockingStateLock) {
            registeredForWrite = false;
            if (fireListener) {
                fireListener = false;
                fire = true;
            }
        }
        if (fire) {
            listener.onWritePossible();
        }
    }
}
