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

import java.io.CharArrayWriter;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;

import org.apache.jasper.JasperException;
import org.apache.jasper.JspCompilationContext;
import org.apache.jasper.runtime.ExceptionUtils;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
import org.apache.tomcat.Jar;

/**
 * JspReader is an input buffer for the JSP parser. It should allow unlimited lookahead and pushback. It also has a
 * bunch of parsing utility methods for understanding html style content.
 */
class JspReader {

    /**
     * Logger.
     */
    private final Log log = LogFactory.getLog(JspReader.class); // must not be static

    /**
     * The current spot in the file.
     */
    private Mark current;

    /**
     * The compilation context.
     */
    private final JspCompilationContext context;

    /**
     * The Jasper error dispatcher.
     */
    private final ErrorDispatcher err;

    /**
     * Constructor.
     *
     * @param ctxt     The compilation context
     * @param fname    The file name
     * @param encoding The file encoding
     * @param jar      ?
     * @param err      The error dispatcher
     *
     * @throws JasperException       If a Jasper-internal error occurs
     * @throws FileNotFoundException If the JSP file is not found (or is unreadable)
     * @throws IOException           If an IO-level error occurs, e.g. reading the file
     */
    JspReader(JspCompilationContext ctxt, String fname, String encoding, Jar jar, ErrorDispatcher err)
            throws JasperException, FileNotFoundException, IOException {

        this(ctxt, fname, JspUtil.getReader(fname, encoding, jar, ctxt, err), err);
    }

    /**
     * Constructor: same as above constructor but with initialized reader to the file given.
     *
     * @param ctxt   The compilation context
     * @param fname  The file name
     * @param reader A reader for the JSP source file
     * @param err    The error dispatcher
     *
     * @throws JasperException If an error occurs parsing the JSP file
     */
    JspReader(JspCompilationContext ctxt, String fname, InputStreamReader reader, ErrorDispatcher err)
            throws JasperException {

        this.context = ctxt;
        this.err = err;

        try {
            CharArrayWriter caw = new CharArrayWriter();
            char[] buf = new char[1024];
            for (int i; (i = reader.read(buf)) != -1;) {
                caw.write(buf, 0, i);
            }
            caw.close();
            current = new Mark(this, caw.toCharArray(), fname);
        } catch (Throwable ex) {
            ExceptionUtils.handleThrowable(ex);
            log.error(Localizer.getMessage("jsp.error.file.cannot.read", fname), ex);
            err.jspError("jsp.error.file.cannot.read", fname);
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (Exception e) {
                    if (log.isDebugEnabled()) {
                        log.debug(Localizer.getMessage("jsp.error.file.close"), e);
                    }
                }
            }
        }
    }


    /**
     * @return JSP compilation context with which this JspReader is associated
     */
    JspCompilationContext getJspCompilationContext() {
        return context;
    }

    /**
     * Checks if the current file has more input.
     *
     * @return True if more reading is possible
     */
    boolean hasMoreInput() {
        return current.cursor < current.stream.length;
    }

    int nextChar() {
        if (!hasMoreInput()) {
            return -1;
        }

        int ch = current.stream[current.cursor];

        current.cursor++;

        if (ch == '\n') {
            current.line++;
            current.col = 0;
        } else {
            current.col++;
        }
        return ch;
    }

    /**
     * A faster approach than calling {@link #mark()} & {@link #nextChar()}. However, this approach is only safe if the
     * mark is only used within the JspReader.
     */
    private int nextChar(Mark mark) {
        if (!hasMoreInput()) {
            return -1;
        }

        int ch = current.stream[current.cursor];

        mark.init(current, true);

        current.cursor++;

        if (ch == '\n') {
            current.line++;
            current.col = 0;
        } else {
            current.col++;
        }
        return ch;
    }

    /**
     * Search the given character, If it was found, then mark the current cursor and the cursor point to next character.
     */
    private Boolean indexOf(char c, Mark mark) {
        if (!hasMoreInput()) {
            return null;
        }

        int end = current.stream.length;
        int ch;
        int line = current.line;
        int col = current.col;
        int i = current.cursor;
        for (; i < end; i++) {
            ch = current.stream[i];

            if (ch == c) {
                mark.update(i, line, col);
            }
            if (ch == '\n') {
                line++;
                col = 0;
            } else {
                col++;
            }
            if (ch == c) {
                current.update(i + 1, line, col);
                return Boolean.TRUE;
            }
        }
        current.update(i, line, col);
        return Boolean.FALSE;
    }

    /**
     * Back up the current cursor by one char, assumes current.cursor > 0, and that the char to be pushed back is not
     * '\n'.
     */
    void pushChar() {
        current.cursor--;
        current.col--;
    }

    String getText(Mark start, Mark stop) {
        Mark oldstart = mark();
        reset(start);
        CharArrayWriter caw = new CharArrayWriter();
        while (!markEquals(stop)) {
            caw.write(nextChar());
        }
        caw.close();
        setCurrent(oldstart);
        return caw.toString();
    }

    /**
     * Read ahead one character without moving the cursor.
     *
     * @return The next character or -1 if no further input is available
     */
    int peekChar() {
        return peekChar(0);
    }

    /**
     * Read ahead the given number of characters without moving the cursor.
     *
     * @param readAhead The number of characters to read ahead. NOTE: This is zero based.
     *
     * @return The requested character or -1 if the end of the input is reached first
     */
    int peekChar(int readAhead) {
        int target = current.cursor + readAhead;
        if (target < current.stream.length) {
            return current.stream[target];
        }
        return -1;
    }

    Mark mark() {
        return new Mark(current);
    }


    /**
     * This method avoids a call to {@link #mark()} when doing comparison.
     */
    private boolean markEquals(Mark another) {
        return another.equals(current);
    }

    void reset(Mark mark) {
        current = new Mark(mark);
    }

    /**
     * Similar to {@link #reset(Mark)} but no new Mark will be created. Therefore, the parameter mark must NOT be used
     * in other places.
     */
    private void setCurrent(Mark mark) {
        current = mark;
    }

    /**
     * search the stream for a match to a string
     *
     * @param string The string to match
     *
     * @return <strong>true</strong> is one is found, the current position in stream is positioned after the search
     *             string, <strong> false</strong> otherwise, position in stream unchanged.
     */
    boolean matches(String string) {
        int len = string.length();
        int cursor = current.cursor;
        int streamSize = current.stream.length;
        if (cursor + len < streamSize) { // Try to scan in memory
            int line = current.line;
            int col = current.col;
            int ch;
            int i = 0;
            for (; i < len; i++) {
                ch = current.stream[i + cursor];
                if (string.charAt(i) != ch) {
                    return false;
                }
                if (ch == '\n') {
                    line++;
                    col = 0;
                } else {
                    col++;
                }
            }
            current.update(i + cursor, line, col);
        } else {
            Mark mark = mark();
            int ch;
            int i = 0;
            do {
                ch = nextChar();
                if (((char) ch) != string.charAt(i++)) {
                    setCurrent(mark);
                    return false;
                }
            } while (i < len);
        }
        return true;
    }

    boolean matchesETag(String tagName) {
        Mark mark = mark();

        if (!matches("</" + tagName)) {
            return false;
        }
        skipSpaces();
        if (nextChar() == '>') {
            return true;
        }

        setCurrent(mark);
        return false;
    }

    boolean matchesETagWithoutLessThan(String tagName) {
        Mark mark = mark();

        if (!matches("/" + tagName)) {
            return false;
        }
        skipSpaces();
        if (nextChar() == '>') {
            return true;
        }

        setCurrent(mark);
        return false;
    }


    /**
     * Looks ahead to see if there are optional spaces followed by the given String. If so, true is returned and those
     * spaces and characters are skipped. If not, false is returned and the position is restored to where we were
     * before.
     */
    boolean matchesOptionalSpacesFollowedBy(String s) {
        Mark mark = mark();

        skipSpaces();
        boolean result = matches(s);
        if (!result) {
            setCurrent(mark);
        }

        return result;
    }

    int skipSpaces() {
        int i = 0;
        while (hasMoreInput() && isSpace()) {
            i++;
            nextChar();
        }
        return i;
    }

    /**
     * Skip until the given string is matched in the stream. When returned, the context is positioned past the end of
     * the match.
     *
     * @param limit The String to match.
     *
     * @return A non-null <code>Mark</code> instance (positioned immediately before the search string) if found,
     *             <strong>null</strong> otherwise.
     */
    Mark skipUntil(String limit) {
        Mark ret = mark();
        int limlen = limit.length();
        char firstChar = limit.charAt(0);
        Boolean result;
        Mark restart = null;

        skip:
        while ((result = indexOf(firstChar, ret)) != null) {
            if (result.booleanValue()) {
                if (restart != null) {
                    restart.init(current, true);
                } else {
                    restart = mark();
                }
                for (int i = 1; i < limlen; i++) {
                    if (peekChar() == limit.charAt(i)) {
                        nextChar();
                    } else {
                        current.init(restart, true);
                        continue skip;
                    }
                }
                return ret;
            }
        }
        return null;
    }

    /**
     * Skip until the given string is matched in the stream, but ignoring chars initially escaped by a '\' and any EL
     * expressions. When returned, the context is positioned past the end of the match.
     *
     * @param limit    The String to match.
     * @param ignoreEL <code>true</code> if something that looks like EL should not be treated as EL.
     *
     * @return A non-null <code>Mark</code> instance (positioned immediately before the search string) if found,
     *             <strong>null</strong> otherwise.
     */
    Mark skipUntilIgnoreEsc(String limit, boolean ignoreEL) {
        Mark ret = mark();
        int limlen = limit.length();
        int ch;
        int prev = 'x'; // Doesn't matter
        char firstChar = limit.charAt(0);
        skip:
        for (ch = nextChar(ret); ch != -1; prev = ch, ch = nextChar(ret)) {
            if (ch == '\\' && prev == '\\') {
                ch = 0; // Double \ is not an escape char anymore
            } else if (prev == '\\') {
                continue;
            } else if (!ignoreEL && (ch == '$' || ch == '#') && peekChar() == '{') {
                // Move beyond the '{'
                nextChar();
                skipELExpression();
            } else if (ch == firstChar) {
                for (int i = 1; i < limlen; i++) {
                    if (peekChar() == limit.charAt(i)) {
                        nextChar();
                    } else {
                        continue skip;
                    }
                }
                return ret;
            }
        }
        return null;
    }

    /**
     * Skip until the given end tag is matched in the stream. When returned, the context is positioned past the end of
     * the tag.
     *
     * @param tag The name of the tag whose ETag (&lt;/tag>) to match.
     *
     * @return A non-null <code>Mark</code> instance (positioned immediately before the ETag) if found,
     *             <strong>null</strong> otherwise.
     */
    Mark skipUntilETag(String tag) {
        Mark ret = skipUntil("</" + tag);
        if (ret != null) {
            skipSpaces();
            if (nextChar() != '>') {
                ret = null;
            }
        }
        return ret;
    }

    /**
     * Parse ELExpressionBody that is a body of ${} or #{} expression. Initial reader position is expected to be just
     * after '${' or '#{' characters.
     * <p>
     * In case of success, this method returns <code>Mark</code> for the last character before the terminating '}' and
     * reader is positioned just after the '}' character. If no terminating '}' is encountered, this method returns
     * <code>null</code>.
     * <p>
     * Starting with EL 3.0, nested paired {}s are supported.
     *
     * @return Mark for the last character of EL expression or <code>null</code>
     */
    Mark skipELExpression() {
        // ELExpressionBody.
        // Starts with "#{" or "${". Ends with "}".
        // May contain quoted "{", "}", '{', or '}' and nested "{...}"
        Mark last = mark();
        boolean singleQuoted = false;
        boolean doubleQuoted = false;
        int nesting = 0;
        int currentChar;
        do {
            currentChar = nextChar(last);
            while (currentChar == '\\' && (singleQuoted || doubleQuoted)) {
                // skip character following '\' within quotes
                // No need to update 'last', as neither of these characters
                // can be the closing '}'.
                nextChar();
                currentChar = nextChar();
            }
            if (currentChar == -1) {
                return null;
            }
            if (currentChar == '"' && !singleQuoted) {
                doubleQuoted = !doubleQuoted;
            } else if (currentChar == '\'' && !doubleQuoted) {
                singleQuoted = !singleQuoted;
            } else if (currentChar == '{' && !doubleQuoted && !singleQuoted) {
                nesting++;
            } else if (currentChar == '}' && !doubleQuoted && !singleQuoted) {
                // Note: This also matches the terminating '}' at which point
                // nesting will be set to -1 - hence the test for
                // while (currentChar != '}' || nesting > -1 ||...) below
                // to continue the loop until the final '}' is detected
                nesting--;
            }
        } while (currentChar != '}' || singleQuoted || doubleQuoted || nesting > -1);

        return last;
    }

    final boolean isSpace() {
        // Note: If this logic changes, also update Node.TemplateText.rtrim()
        return peekChar() <= ' ';
    }

    /**
     * Parse a space delimited token. If quoted the token will consume all characters up to a matching quote, otherwise,
     * it consumes up to the first delimiter character.
     *
     * @param quoted If <strong>true</strong> accept quoted strings.
     */
    String parseToken(boolean quoted) throws JasperException {
        StringBuilder StringBuilder = new StringBuilder();
        skipSpaces();
        StringBuilder.setLength(0);

        if (!hasMoreInput()) {
            return "";
        }

        int ch = peekChar();

        if (quoted) {
            if (ch == '"' || ch == '\'') {

                char endQuote = ch == '"' ? '"' : '\'';
                // Consume the open quote:
                ch = nextChar();
                for (ch = nextChar(); ch != -1 && ch != endQuote; ch = nextChar()) {
                    if (ch == '\\') {
                        ch = nextChar();
                    }
                    StringBuilder.append((char) ch);
                }
                // Check end of quote, skip closing quote:
                if (ch == -1) {
                    err.jspError(mark(), "jsp.error.quotes.unterminated");
                }
            } else {
                err.jspError(mark(), "jsp.error.attr.quoted");
            }
        } else {
            if (!isDelimiter()) {
                // Read value until delimiter is found:
                do {
                    ch = nextChar();
                    // Take care of the quoting here.
                    if (ch == '\\') {
                        if (peekChar() == '"' || peekChar() == '\'' || peekChar() == '>' || peekChar() == '%') {
                            ch = nextChar();
                        }
                    }
                    StringBuilder.append((char) ch);
                } while (!isDelimiter());
            }
        }

        return StringBuilder.toString();
    }


    /**
     * Parse utils - Is current character a token delimiter ? Delimiters are currently defined to be =, &gt;, &lt;, ",
     * and ' or any space character as defined by <code>isSpace</code>.
     *
     * @return A boolean.
     */
    private boolean isDelimiter() {
        if (!isSpace()) {
            int ch = peekChar();
            // Look for a single-char work delimiter:
            if (ch == '=' || ch == '>' || ch == '"' || ch == '\'' || ch == '/') {
                return true;
            }
            // Look for an end-of-comment or end-of-tag:
            if (ch == '-') {
                Mark mark = mark();
                if (((ch = nextChar()) == '>') || ((ch == '-') && (nextChar() == '>'))) {
                    setCurrent(mark);
                    return true;
                } else {
                    setCurrent(mark);
                    return false;
                }
            }
            return false;
        } else {
            return true;
        }
    }
}

