/*
 * Copyright 1999,2004 The Apache Software Foundation.
 * 
 * Licensed 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;

/**
 * This class implements a parser for EL expressions.
 *
 * It takes strings of the form xxx${..}yyy${..}zzz etc, and turn it into
 * a ELNode.Nodes.
 *
 * Currently, it only handles text outside ${..} and functions in ${ ..}.
 *
 * @author Kin-man Chung
 */

public class ELParser {

    private Token curToken;	// current token
    private ELNode.Nodes expr;
    private ELNode.Nodes ELexpr;
    private int index;		// Current index of the expression
    private String expression;	// The EL expression
    private boolean escapeBS;	// is '\' an escape char in text outside EL?

    private static final String reservedWords[] = {
        "and", "div", "empty", "eq", "false",
        "ge", "gt", "instanceof", "le", "lt", "mod",
        "ne", "not", "null", "or", "true"};

    public ELParser(String expression) {
	index = 0;
	this.expression = expression;
	expr = new ELNode.Nodes();
    }

    /**
     * Parse an EL expression
     * @param expression The input expression string of the form
     *                   Char* ('${' Char* '}')* Char*
     * @return Parsed EL expression in ELNode.Nodes
     */
    public static ELNode.Nodes parse(String expression) {
	ELParser parser = new ELParser(expression);
	while (parser.hasNextChar()) {
	    String text = parser.skipUntilEL();
	    if (text.length() > 0) {
		parser.expr.add(new ELNode.Text(text));
	    }
	    ELNode.Nodes elexpr = parser.parseEL();
	    if (! elexpr.isEmpty()) {
		parser.expr.add(new ELNode.Root(elexpr));
	    }
	}
	return parser.expr;
    }

    /**
     * Parse an EL expression string '${...}'
     *@return An ELNode.Nodes representing the EL expression
     * TODO: Currently only parsed into functions and text strings.  This
     *       should be rewritten for a full parser.
     */
    private ELNode.Nodes parseEL() {

	StringBuffer buf = new StringBuffer();
	ELexpr = new ELNode.Nodes();
	while (hasNext()) {
	    curToken = nextToken();
	    if (curToken instanceof Char) {
		if (curToken.toChar() == '}') {
		    break;
		}
		buf.append(curToken.toChar());
	    } else {
		// Output whatever is in buffer
		if (buf.length() > 0) {
		    ELexpr.add(new ELNode.ELText(buf.toString()));
		}
		if (!parseFunction()) {
		    ELexpr.add(new ELNode.ELText(curToken.toString()));
		}
	    }
	}
	if (buf.length() > 0) {
	    ELexpr.add(new ELNode.ELText(buf.toString()));
	}

	return ELexpr;
    }

    /**
     * Parse for a function
     * FunctionInvokation ::= (identifier ':')? identifier '('
     *			      (Expression (,Expression)*)? ')'
     * Note: currently we don't parse arguments
     */
    private boolean parseFunction() {
	if (! (curToken instanceof Id) || isELReserved(curToken.toString())) {
	    return false;
	}
	String s1 = null;                 // Function prefix
	String s2 = curToken.toString();  // Function name
	int mark = getIndex();
	if (hasNext()) {
	    Token t = nextToken();
	    if (t.toChar() == ':') {
		if (hasNext()) {
		    Token t2 = nextToken();
		    if (t2 instanceof Id) {
			s1 = s2;
			s2 = t2.toString();
			if (hasNext()) {
			    t = nextToken();
			}
		    }
		}
	    }
	    if (t.toChar() == '(') {
		ELexpr.add(new ELNode.Function(s1, s2));
		return true;
	    }
	}
	setIndex(mark);
	return false;
    }

    /**
     * Test if an id is a reserved word in EL
     */
    private boolean isELReserved(String id) {
        int i = 0;
        int j = reservedWords.length;
        while (i < j) {
            int k = (i+j)/2;
            int result = reservedWords[k].compareTo(id);
            if (result == 0) {
                return true;
            }
            if (result < 0) {
                i = k+1;
            } else {
                j = k;
            }
        }
        return false;
    }

    /**
     * Skip until an EL expression ('${') is reached, allowing escape sequences
     * '\\' and '\$'.
     * @return The text string up to the EL expression
     */
    private String skipUntilEL() {
	char prev = 0;
	StringBuffer buf = new StringBuffer();
	while (hasNextChar()) {
	    char ch = nextChar();
	    if (prev == '\\') {
		prev = 0;
		if (ch == '\\') {
		    buf.append('\\');
		    if (!escapeBS)
			prev = '\\';
		} else if (ch == '$') {
		    buf.append('$');
		}
		// else error!
	    } else if (prev == '$') {
		if (ch == '{') {
		    prev = 0;
		    break;
		} 
		buf.append('$');
		buf.append(ch);
	    } else if (ch == '\\' || ch == '$') {
		prev = ch;
	    } else {
		buf.append(ch);
	    }
	}
	if (prev != 0) {
	    buf.append(prev);
	}
	return buf.toString();
    }

    /*
     * @return true if there is something left in EL expression buffer other
     *         than white spaces.
     */
    private boolean hasNext() {
	skipSpaces();
	return hasNextChar();
    }

    /*
     * @return The next token in the EL expression buffer.
     */
    private Token nextToken() {
	skipSpaces();
	if (hasNextChar()) {
	    char ch = nextChar();
	    if (Character.isJavaIdentifierStart(ch)) {
		StringBuffer buf = new StringBuffer();
		buf.append(ch);
		while ((ch = peekChar()) != -1 &&
				Character.isJavaIdentifierPart(ch)) {
		    buf.append(ch);
		    nextChar();
		}
		return new Id(buf.toString());
	    }

	    if (ch == '\'' || ch == '"') {
		return parseQuotedChars(ch);
	    } else {
		// For now...
		return new Char(ch);
	    }
	}
	return null;
    }

    /*
     * Parse a string in single or double quotes, allowing for escape sequences
     * '\\', and ('\"', or "\'")
     */
    private Token parseQuotedChars(char quote) {
	StringBuffer buf = new StringBuffer();
	buf.append(quote);
	while (hasNextChar()) {
	    char ch = nextChar();
	    if (ch == '\\') {
		ch = nextChar();
		if (ch == '\\' || ch == quote) {
		    buf.append(ch);
		}
		// else error!
	    } else if (ch == quote) {
		buf.append(ch);
		break;
	    } else {
		buf.append(ch);
	    }
	}
	return new QuotedString(buf.toString());
    }

    /*
     * A collection of low level parse methods dealing with character in
     * the EL expression buffer.
     */

    private void skipSpaces() {
	while (hasNextChar()) {
	    if (expression.charAt(index) > ' ')
		break;
	    index++;
	}
    }

    private boolean hasNextChar() {
	return index < expression.length();
    }

    private char nextChar() {
	if (index >= expression.length()) {
	    return (char)-1;
	}
	return expression.charAt(index++);
    }

    private char peekChar() {
	if (index >= expression.length()) {
	    return (char)-1;
	}
	return expression.charAt(index);
    }

    private int getIndex() {
	return index;
    }

    private void setIndex(int i) {
	index = i;
    }

    /*
     * Represents a token in EL expression string
     */
    private static class Token {

	char toChar() {
	    return 0;
	}

	public String toString() {
	    return "";
	}
    }

    /*
     * Represents an ID token in EL
     */
    private static class Id extends Token {
	String id;

	Id(String id) {
	    this.id = id;
	}

	public String toString() {
	    return id;
	}
    }

    /*
     * Represents a character token in EL
     */
    private static class Char extends Token {

	private char ch;

	Char(char ch) {
	    this.ch = ch;
	}

	char toChar() {
	    return ch;
	}

	public String toString() {
	    return (new Character(ch)).toString();
	}
    }

    /*
     * Represents a quoted (single or double) string token in EL
     */
    private static class QuotedString extends Token {

	private String value;

	QuotedString(String v) {
	    this.value = v;
	}

	public String toString() {
	    return value;
	}
    }
}

