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

import java.io.CharArrayReader;
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;

import jakarta.servlet.jsp.JspWriter;
import jakarta.servlet.jsp.tagext.BodyContent;

import org.apache.jasper.compiler.Localizer;

/**
 * Write text to a character-output stream, buffering characters to provide efficient writing of single characters,
 * arrays, and strings. Provide support for discarding the output that has been buffered.
 */
public class BodyContentImpl extends BodyContent {

    private final boolean limitBuffer;
    private final int tagBufferSize;

    private char[] cb;
    private int nextChar;
    private boolean closed;

    /**
     * Enclosed writer to which any output is written
     */
    private Writer writer;

    /**
     * Constructor.
     *
     * @param enclosingWriter The wrapped writer
     * @param limitBuffer     <code>true</code> to discard large buffers
     * @param tagBufferSize   the buffer size
     */
    public BodyContentImpl(JspWriter enclosingWriter, boolean limitBuffer, int tagBufferSize) {
        super(enclosingWriter);
        this.limitBuffer = limitBuffer;
        this.tagBufferSize = tagBufferSize;
        cb = new char[tagBufferSize];
        bufferSize = cb.length;
        nextChar = 0;
        closed = false;
    }

    @Override
    public void write(int c) throws IOException {
        if (writer != null) {
            writer.write(c);
        } else {
            ensureOpen();
            if (nextChar >= bufferSize) {
                reAllocBuff(1);
            }
            cb[nextChar++] = (char) c;
        }
    }

    @Override
    public void write(char[] cbuf, int off, int len) throws IOException {
        if (writer != null) {
            writer.write(cbuf, off, len);
        } else {
            ensureOpen();

            if ((off < 0) || (off > cbuf.length) || (len < 0) || ((off + len) > cbuf.length) || ((off + len) < 0)) {
                throw new IndexOutOfBoundsException();
            } else if (len == 0) {
                return;
            }

            if (len >= bufferSize - nextChar) {
                reAllocBuff(len);
            }

            System.arraycopy(cbuf, off, cb, nextChar, len);
            nextChar += len;
        }
    }

    @Override
    public void write(char[] buf) throws IOException {
        if (writer != null) {
            writer.write(buf);
        } else {
            write(buf, 0, buf.length);
        }
    }

    @Override
    public void write(String s, int off, int len) throws IOException {
        if (writer != null) {
            writer.write(s, off, len);
        } else {
            ensureOpen();
            if (len >= bufferSize - nextChar) {
                reAllocBuff(len);
            }

            s.getChars(off, off + len, cb, nextChar);
            nextChar += len;
        }
    }

    @Override
    public void write(String s) throws IOException {
        if (writer != null) {
            writer.write(s);
        } else {
            write(s, 0, s.length());
        }
    }

    @Override
    public void newLine() throws IOException {
        if (writer != null) {
            writer.write(System.lineSeparator());
        } else {
            write(System.lineSeparator());
        }
    }

    @Override
    public void print(boolean b) throws IOException {
        if (writer != null) {
            writer.write(b ? "true" : "false");
        } else {
            write(b ? "true" : "false");
        }
    }

    @Override
    public void print(char c) throws IOException {
        if (writer != null) {
            writer.write(String.valueOf(c));
        } else {
            write(String.valueOf(c));
        }
    }

    @Override
    public void print(int i) throws IOException {
        if (writer != null) {
            writer.write(String.valueOf(i));
        } else {
            write(String.valueOf(i));
        }
    }

    @Override
    public void print(long l) throws IOException {
        if (writer != null) {
            writer.write(String.valueOf(l));
        } else {
            write(String.valueOf(l));
        }
    }

    @Override
    public void print(float f) throws IOException {
        if (writer != null) {
            writer.write(String.valueOf(f));
        } else {
            write(String.valueOf(f));
        }
    }

    @Override
    public void print(double d) throws IOException {
        if (writer != null) {
            writer.write(String.valueOf(d));
        } else {
            write(String.valueOf(d));
        }
    }

    @Override
    public void print(char[] s) throws IOException {
        if (writer != null) {
            writer.write(s);
        } else {
            write(s);
        }
    }

    @Override
    public void print(String s) throws IOException {
        if (s == null) {
            s = "null";
        }
        if (writer != null) {
            writer.write(s);
        } else {
            write(s);
        }
    }

    @Override
    public void print(Object obj) throws IOException {
        if (writer != null) {
            writer.write(String.valueOf(obj));
        } else {
            write(String.valueOf(obj));
        }
    }

    @Override
    public void println() throws IOException {
        newLine();
    }

    @Override
    public void println(boolean x) throws IOException {
        print(x);
        println();
    }

    @Override
    public void println(char x) throws IOException {
        print(x);
        println();
    }

    @Override
    public void println(int x) throws IOException {
        print(x);
        println();
    }

    @Override
    public void println(long x) throws IOException {
        print(x);
        println();
    }

    @Override
    public void println(float x) throws IOException {
        print(x);
        println();
    }

    @Override
    public void println(double x) throws IOException {
        print(x);
        println();
    }

    @Override
    public void println(char[] x) throws IOException {
        print(x);
        println();
    }

    @Override
    public void println(String x) throws IOException {
        print(x);
        println();
    }

    @Override
    public void println(Object x) throws IOException {
        print(x);
        println();
    }

    @Override
    public void clear() throws IOException {
        if (writer != null) {
            throw new IOException();
        } else {
            nextChar = 0;
            if (limitBuffer && (cb.length > tagBufferSize)) {
                cb = new char[tagBufferSize];
                bufferSize = cb.length;
            }
        }
    }

    @Override
    public void clearBuffer() throws IOException {
        if (writer == null) {
            this.clear();
        }
    }

    @Override
    public void close() throws IOException {
        if (writer != null) {
            writer.close();
        } else {
            closed = true;
        }
    }

    @Override
    public int getBufferSize() {
        // According to the spec, the JspWriter returned by
        // JspContext.pushBody(java.io.Writer writer) must behave as
        // though it were unbuffered. This means that its getBufferSize()
        // must always return 0.
        return (writer == null) ? bufferSize : 0;
    }

    @Override
    public int getRemaining() {
        return (writer == null) ? bufferSize - nextChar : 0;
    }

    @Override
    public Reader getReader() {
        return (writer == null) ? new CharArrayReader(cb, 0, nextChar) : null;
    }

    @Override
    public String getString() {
        return (writer == null) ? new String(cb, 0, nextChar) : null;
    }

    @Override
    public void writeOut(Writer out) throws IOException {
        if (writer == null) {
            out.write(cb, 0, nextChar);
            // Flush not called as the writer passed could be a BodyContent, and
            // it doesn't allow to flush.
        }
    }

    /**
     * Sets the writer to which all output is written.
     */
    void setWriter(Writer writer) {
        this.writer = writer;
        closed = false;
        if (writer == null) {
            clearBody();
        }
    }

    /**
     * This method shall "reset" the internal state of a BodyContentImpl, releasing all internal references, and
     * preparing it for potential reuse by a later invocation of {@link PageContextImpl#pushBody(Writer)}.
     * <p>
     * Note, that BodyContentImpl instances are usually owned by a PageContextImpl instance, and PageContextImpl
     * instances are recycled and reused.
     *
     * @see PageContextImpl#release()
     */
    protected void recycle() {
        this.writer = null;
        try {
            this.clear();
        } catch (IOException ignore) {
            // ignore
        }
    }

    private void ensureOpen() throws IOException {
        if (closed) {
            throw new IOException(Localizer.getMessage("jsp.error.stream.closed"));
        }
    }

    /**
     * Reallocates buffer since the spec requires it to be unbounded.
     */
    private void reAllocBuff(int len) {

        if (bufferSize + len <= cb.length) {
            bufferSize = cb.length;
            return;
        }

        if (len < cb.length) {
            len = cb.length;
        }

        char[] tmp = new char[cb.length + len];
        System.arraycopy(cb, 0, tmp, 0, cb.length);
        cb = tmp;
        bufferSize = cb.length;
    }


}
