/*
 * 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 javax.el.ELContext;
import javax.el.ELException;
import javax.el.ELManager;
import javax.el.ExpressionFactory;
import javax.el.ValueExpression;

import org.junit.Assert;
import org.junit.Test;

import org.apache.jasper.JasperException;
import org.apache.jasper.compiler.ELNode.Nodes;
import org.apache.jasper.compiler.ELParser.TextBuilder;

/**
 * You will need to keep your wits about you when working with this class. Keep
 * in mind the following:
 * <ul>
 * <li>If in doubt, read the EL and JSP specifications. Twice.</li>
 * <li>The escaping rules are complex and subtle. The explanation below (as well
 *     as the tests and the implementation) may have missed an edge case despite
 *     trying hard not to.
 * <li>The strings passed to {@link #doTestParser(String,String)} are Java
 *     escaped in the source code and will be unescaped before being used.</li>
 * <li>LiteralExpressions always occur outside of "${...}" and "#{...}". Literal
 *     expressions escape '$' and '#' with '\\'</li>
 * <li>LiteralStrings always occur inside "${...}" or "#{...}". Literal strings
 *     escape '\'', '\"' and '\\' with '\\'. Escaping '\"' is optional if the
 *     literal string is delimited by '\''. Escaping '\'' is optional if the
 *     literal string is delimited by '\"'.</li>
 * </ul>
 */
public class TestELParser {

    @Test
    public void testText() throws JasperException {
        doTestParser("foo", "foo");
    }


    @Test
    public void testLiteral() throws JasperException {
        doTestParser("${'foo'}", "foo");
    }


    @Test
    public void testVariable() throws JasperException {
        doTestParser("${test}", null);
    }


    @Test
    public void testFunction01() throws JasperException {
        doTestParser("${do(x)}", null);
    }


    @Test
    public void testFunction02() throws JasperException {
        doTestParser("${do:it(x)}", null);
    }


    @Test
    public void testFunction03() throws JasperException {
        doTestParser("${do:it(x,y)}", null);
    }


    @Test
    public void testFunction04() throws JasperException {
        doTestParser("${do:it(x,y,z)}", null);
    }


    @Test
    public void testFunction05() throws JasperException {
        doTestParser("${do:it(x, '\\\\y',z)}", null);
    }


    @Test
    public void testCompound01() throws JasperException {
        doTestParser("1${'foo'}1", "1foo1");
    }


    @Test
    public void testCompound02() throws JasperException {
        doTestParser("1${test}1", null);
    }


    @Test
    public void testCompound03() throws JasperException {
        doTestParser("${foo}${bar}", null);
    }


    @Test
    public void testTernary01() throws JasperException {
        doTestParser("${true?true:false}", "true");
    }


    @Test
    public void testTernary02() throws JasperException {
        doTestParser("${a==1?true:false}", null);
    }


    @Test
    public void testTernary03() throws JasperException {
        doTestParser("${a eq1?true:false}", null);
    }


    @Test
    public void testTernary04() throws JasperException {
        doTestParser(" ${ a eq 1 ? true : false } ", null);
    }


    @Test
    public void testTernary05() throws JasperException {
        // Note this is invalid EL
        doTestParser("${aeq1?true:false}", null);
    }


    @Test
    public void testTernary06() throws JasperException {
        doTestParser("${do:it(a eq1?true:false,y)}", null);
    }


    @Test
    public void testTernary07() throws JasperException {
        doTestParser(" ${ do:it( a eq 1 ? true : false, y ) } ", null);
    }


    @Test
    public void testTernary08() throws JasperException {
        doTestParser(" ${ do:it ( a eq 1 ? true : false, y ) } ", null);
    }


    @Test
    public void testTernary09() throws JasperException {
        doTestParser(" ${ do : it ( a eq 1 ? true : false, y ) } ", null);
    }


    @Test
    public void testTernary10() throws JasperException {
        doTestParser(" ${!empty my:link(foo)} ", null);
    }


    @Test
    public void testTernary11() throws JasperException {
        doTestParser("${true?'true':'false'}", "true");
    }


    @Test
    public void testTernary12() throws JasperException {
        doTestParser("${true?'tr\"ue':'false'}", "tr\"ue");
    }


    @Test
    public void testTernary13() throws JasperException {
        doTestParser("${true?'tr\\'ue':'false'}", "tr'ue");
    }


    @Test
    public void testTernaryBug56031() throws JasperException {
        doTestParser("${my:link(!empty registration ? registration : '/test/registration')}", null);
    }


    @Test
    public void testQuotes01() throws JasperException {
        doTestParser("'", "'");
    }


    @Test
    public void testQuotes02() throws JasperException {
        doTestParser("'${foo}'", null);
    }


    @Test
    public void testQuotes03() throws JasperException {
        doTestParser("'${'foo'}'", "'foo'");
    }


    @Test
    public void testEscape01() throws JasperException {
        doTestParser("${'\\\\'}", "\\");
    }


    @Test
    public void testEscape02() throws JasperException {
        doTestParser("\\\\x${'\\\\'}", "\\\\x\\");
    }


    @Test
    public void testEscape03() throws JasperException {
        doTestParser("\\\\", "\\\\");
    }


    @Test
    public void testEscape04() throws JasperException {
        // When parsed as EL in JSP the escaping of $ as \$ is optional
        doTestParser("\\$", "\\$", "$");
    }


    @Test
    public void testEscape05() throws JasperException {
        // When parsed as EL in JSP the escaping of # as \# is optional
        doTestParser("\\#", "\\#", "#");
    }


    @Test
    public void testEscape07() throws JasperException {
        doTestParser("${'\\\\$'}", "\\$");
    }


    @Test
    public void testEscape08() throws JasperException {
        doTestParser("${'\\\\#'}", "\\#");
    }


    @Test
    public void testEscape09() throws JasperException {
        doTestParser("\\${", "${");
    }


    @Test
    public void testEscape10() throws JasperException {
        doTestParser("\\#{", "#{");
    }


    @Test
    public void testEscape11() throws JasperException {
        // Bug 56612
        doTestParser("${'\\'\\''}", "''");
    }


    private void doTestParser(String input, String expected) throws JasperException {
        doTestParser(input, expected, input);
    }

    private void doTestParser(String input, String expectedResult, String expectedBuilderOutput) throws JasperException {

        ELException elException = null;
        String elResult = null;

        // Don't try and evaluate expressions that depend on variables or functions
        if (expectedResult != null) {
            try {
                ELManager manager = new ELManager();
                ELContext context = manager.getELContext();
                ExpressionFactory factory = ELManager.getExpressionFactory();
                ValueExpression ve = factory.createValueExpression(context, input, String.class);
                elResult = ve.getValue(context).toString();
                Assert.assertEquals(expectedResult, elResult);
            } catch (ELException ele) {
                elException = ele;
            }
        }

        Nodes nodes = null;
        try {
            nodes = ELParser.parse(input, false);
            Assert.assertNull(elException);
        } catch (IllegalArgumentException iae) {
            Assert.assertNotNull(elResult, elException);
            // Not strictly true but enables us to report both
            iae.initCause(elException);
            throw iae;
        }

        TextBuilder textBuilder = new TextBuilder(false);

        nodes.visit(textBuilder);

        Assert.assertEquals(expectedBuilderOutput, textBuilder.getText());
    }
}
