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

import java.io.StringReader;
import java.io.StringWriter;
import java.util.Map;
import java.util.Set;
import org.apache.commons.jexl3.internal.LexicalScope;
import org.junit.Assert;
import org.junit.Test;

/**
 * Test cases for lexical option and feature.
 */
public class LexicalTest {

    @Test
    public void testLexical0a() throws Exception {
        runLexical0(false);
    }

    @Test
    public void testLexical0b() throws Exception {
        runLexical0(true);
    }

    void runLexical0(boolean feature) throws Exception {
        JexlFeatures f = new JexlFeatures();
        f.lexical(feature);
        JexlEngine jexl = new JexlBuilder().strict(true).features(f).create();
        JexlEvalContext ctxt = new JexlEvalContext();
        JexlOptions options = ctxt.getEngineOptions();
        // ensure errors will throw
        options.setLexical(true);
        JexlScript script;
        try {
            script = jexl.createScript("var x = 0; var x = 1;");
            if (!feature) {
                script.execute(ctxt);
            }
            Assert.fail();
        } catch (JexlException xany) {
            String ww = xany.toString();
        }
        try {
            script = jexl.createScript("var x = 0; for(var y : null) { var y = 1;");
            if (!feature) {
                script.execute(ctxt);
            }
            Assert.fail();
        } catch (JexlException xany) {
            String ww = xany.toString();
        }
        try {
            script = jexl.createScript("var x = 0; for(var x : null) {};");
            if (!feature) {
                script.execute(ctxt);
            }
            Assert.fail();
        } catch (JexlException xany) {
            String ww = xany.toString();
        }
        try {
            script = jexl.createScript("(x)->{ var x = 0; x; }");
            if (!feature) {
                script.execute(ctxt);
            }
            Assert.fail();
        } catch (JexlException xany) {
            String ww = xany.toString();
        }
        try {
            script = jexl.createScript("var x; if (true) { if (true) { var x = 0; x; } }");
            if (!feature) {
                script.execute(ctxt);
            }
            Assert.fail();
        } catch (JexlException xany) {
            String ww = xany.toString();
        }
        try {
            script = jexl.createScript("if (a) { var y = (x)->{ var x = 0; x; }; y(2) }", "a");
            if (!feature) {
                script.execute(ctxt);
            }
            Assert.fail();
        } catch (JexlException xany) {
            String ww = xany.toString();
        }
        try {
            script = jexl.createScript("(x)->{ for(var x : null) { x; } }");
            if (!feature) {
                script.execute(ctxt, 42);
            }
            Assert.fail();
        } catch (JexlException xany) {
            String ww = xany.toString();
        }
        // no fail
        script = jexl.createScript("var x = 32; (()->{ for(var x : null) { x; }})();");
        if (!feature) {
            script.execute(ctxt, 42);
        }
    }

    @Test
    public void testLexical1a() throws Exception {
        runLexical1(false);
    }

    @Test
    public void testLexical1b() throws Exception {
        runLexical1(true);
    }

    void runLexical1(boolean shade) throws Exception {
        JexlEngine jexl = new JexlBuilder().strict(true).create();
        JexlEvalContext ctxt = new JexlEvalContext();
        Object result;
        ctxt.set("x", 4242);
        JexlOptions options = ctxt.getEngineOptions();
        // ensure errors will throw
        options.setLexical(true);
        options.setLexicalShade(shade);
        JexlScript script;
        try {
            // if local shade, x is undefined
            script = jexl.createScript("{ var x = 0; } x");
            script.execute(ctxt);
            if (shade) {
                Assert.fail("local shade means 'x' should be undefined");
            }
        } catch (JexlException xany) {
            if (!shade) {
                throw xany;
            }
        }
        try {
            // if local shade, x = 42 is undefined
            script = jexl.createScript("{ var x = 0; } x = 42");
            script.execute(ctxt);
            if (shade) {
                Assert.fail("local shade means 'x = 42' should be undefined");
            }
        } catch (JexlException xany) {
            if (!shade) {
                throw xany;
            }
        }
        try {
            // if local shade, x = 42 is undefined
            script = jexl.createScript("{ var x = 0; } y = 42");
            script.execute(ctxt);
            if (shade) {
                Assert.fail("local shade means 'y = 42' should be undefined (y is undefined)");
            }
        } catch (JexlException xany) {
            if (!shade) {
                throw xany;
            }
        }
        // no fail
        script = jexl.createScript("var x = 32; (()->{ for(var x : null) { x; }})();");
        //if (!feature) {
            script.execute(ctxt, 42);
        //}
        // y being defined as global
        ctxt.set("y", 4242);
        try {
            // if no shade and global y being defined,
            script = jexl.createScript("{ var y = 0; } y = 42");
            result = script.execute(ctxt);
            if (!shade) {
                Assert.assertEquals(42, result);
            } else {
                Assert.fail("local shade means 'y = 42' should be undefined");
            }
        } catch (JexlException xany) {
            if (!shade) {
                throw xany;
            }
        }
    }

    @Test
    public void testLexical1() throws Exception {
        JexlEngine jexl = new JexlBuilder().strict(true).create();
        JexlEvalContext ctxt = new JexlEvalContext();
        JexlOptions options = ctxt.getEngineOptions();
        // ensure errors will throw
        options.setLexical(true);
        JexlScript script;
        Object result;

        script = jexl.createScript("var x = 0; for(var y : [1]) { var x = 42; return x; };");
        try {
        result = script.execute(ctxt);
        //Assert.assertEquals(42, result);
            Assert.fail();
        } catch (JexlException xany) {
            String ww = xany.toString();
        }

        try {
            script = jexl.createScript("(x)->{ if (x) { var x = 7 * (x + x); x; } }");
            result = script.execute(ctxt, 3);
            Assert.fail();
        } catch (JexlException xany) {
            String ww = xany.toString();
        }

        script = jexl.createScript("{ var x = 0; } var x = 42; x");
        result = script.execute(ctxt, 21);
        Assert.assertEquals(42, result);
    }

    @Test
    public void testLexical2a() throws Exception {
        runLexical2(true);
    }

    @Test
    public void testLexical2b() throws Exception {
        runLexical2(false);
    }

    protected void runLexical2(boolean lexical) throws Exception {
        JexlEngine jexl = new JexlBuilder().strict(true).lexical(lexical).create();
        JexlContext ctxt = new MapContext();
        JexlScript script = jexl.createScript("{var x = 42}; {var x; return x; }");
        Object result = script.execute(ctxt);
        if (lexical) {
            Assert.assertNull(result);
        } else {
            Assert.assertEquals(42, result);
        }
    }

    @Test
    public void testLexical3() throws Exception {
        String str = "var s = {}; for (var i : [1]) s.add(i); s";
        JexlEngine jexl = new JexlBuilder().strict(true).lexical(true).create();
        JexlScript e = jexl.createScript(str);
        JexlContext jc = new MapContext();
        Object o = e.execute(jc);
        Assert.assertTrue(((Set)o).contains(1));

        e = jexl.createScript(str);
        o = e.execute(jc);
        Assert.assertTrue(((Set)o).contains(1));
    }

    @Test
    public void testLexical4() throws Exception {
        JexlEngine Jexl = new JexlBuilder().silent(false).strict(true).lexical(true).create();
        JxltEngine Jxlt = Jexl.createJxltEngine();
        JexlContext ctxt = new MapContext();
        String rpt
                = "<report>\n"
                + "\n$$var y = 1; var x = 2;"
                + "\n${x + y}"
                + "\n</report>\n";
        JxltEngine.Template t = Jxlt.createTemplate("$$", new StringReader(rpt));
        StringWriter strw = new StringWriter();
        t.evaluate(ctxt, strw);
        String output = strw.toString();
        String ctl = "<report>\n\n3\n</report>\n";
        Assert.assertEquals(ctl, output);
    }

    @Test
    public void testLexical5() throws Exception {
        JexlEngine jexl = new JexlBuilder().strict(true).lexical(true).create();
        JexlContext ctxt = new MapContext();
        JexlScript script;
        Object result;
        script = jexl.createScript("var x = 42; var z = 169; var y = () -> { {var x = -42; }; return x; }; y()");
        try {
            result = script.execute(ctxt);
            Assert.assertEquals(42, result);
        } catch (JexlException xany) {
            String ww = xany.toString();
            Assert.fail(ww);
        }
    }
        
    @Test
    public void testLexical6a() throws Exception {
        String str = "i = 0; { var i = 32; }; i";
        JexlEngine jexl = new JexlBuilder().strict(true).lexical(true).create();
        JexlScript e = jexl.createScript(str);
        JexlContext ctxt = new MapContext();
        Object o = e.execute(ctxt);
        Assert.assertEquals(0, o);
    }   

    @Test
    public void testLexical6b() throws Exception {
        String str = "i = 0; { var i = 32; }; i";
        JexlEngine jexl = new JexlBuilder().strict(true).lexical(true).lexicalShade(true).create();
        JexlScript e = jexl.createScript(str);
        JexlContext ctxt = new MapContext();
        try {
            Object o = e.execute(ctxt);
            Assert.fail("i should be shaded");
        } catch (JexlException xany) {
            Assert.assertNotNull(xany);
        }
    }

    @Test
    public void testLexical6c() throws Exception {
        String str = "i = 0; for (var i : [42]) i; i";
        JexlEngine jexl = new JexlBuilder().strict(true).lexical(true).lexicalShade(false).create();
        JexlScript e = jexl.createScript(str);
        JexlContext ctxt = new MapContext();
        Object o = e.execute(ctxt);
        Assert.assertEquals(0, o);
    }

    @Test
    public void testLexical6d() throws Exception {
        String str = "i = 0; for (var i : [42]) i; i";
        JexlEngine jexl = new JexlBuilder().strict(true).lexical(true).lexicalShade(true).create();
        JexlScript e = jexl.createScript(str);
        JexlContext ctxt = new MapContext();
        try {
            Object o = e.execute(ctxt);
            Assert.fail("i should be shaded");
        } catch (JexlException xany) {
            Assert.assertNotNull(xany);
        }
    }
    
    @Test
    public void testPragmaOptions() throws Exception {
        // same as 6d but using a pragma
        String str = "#pragma jexl.options '+strict +lexical +lexicalShade -safe'\n"
                + "i = 0; for (var i : [42]) i; i";
        JexlEngine jexl = new JexlBuilder().strict(false).create();
        JexlScript e = jexl.createScript(str);
        JexlContext ctxt = new MapContext();
        try {
            Object o = e.execute(ctxt);
            Assert.fail("i should be shaded");
        } catch (JexlException xany) {
            Assert.assertNotNull(xany);
        }
    }
    
    @Test
    public void testPragmaNoop() throws Exception {
        // unknow pragma
        String str = "#pragma jexl.options 'no effect'\ni = -42; for (var i : [42]) i; i";
        JexlEngine jexl = new JexlBuilder().lexical(false).strict(true).create();
        JexlScript e = jexl.createScript(str);
        JexlContext ctxt = new MapContext();
        Object result = e.execute(ctxt);
        Assert.assertEquals(42, result);
    }
    
    
    @Test
    public void testScopeFrame() throws Exception {
        LexicalScope scope = new LexicalScope(null);
        for(int i = 0; i < 128; i += 2) {
            Assert.assertTrue(scope.declareSymbol(i));
            Assert.assertFalse(scope.declareSymbol(i));
        }
        for(int i = 0; i < 128; i += 2) {
            Assert.assertTrue(scope.hasSymbol(i));
            Assert.assertFalse(scope.hasSymbol(i + 1));
        }
    }
    
    @Test
    public void testContextualOptions0() throws Exception {
        JexlFeatures f= new JexlFeatures();
        JexlEngine jexl = new JexlBuilder().features(f).strict(true).create();
        JexlEvalContext ctxt = new JexlEvalContext();
        JexlOptions options = ctxt.getEngineOptions();
        options.setSharedInstance(false);
        options.setLexical(true);
        options.setLexicalShade(true);
        ctxt.set("options", options);
        JexlScript script = jexl.createScript("{var x = 42;} options.lexical = false; options.lexicalShade=false; x");
        try {
        Object result = script.execute(ctxt);
        Assert.fail("setting options.lexical should have no effect during execution");
        } catch(JexlException xf) {
            Assert.assertNotNull(xf);
        }
    }
    
    /**
     * Context augmented with a tryCatch.
     */
    public static class TestContext extends JexlEvalContext {
        public TestContext() {}
        public TestContext(Map<String, Object> map) {
            super(map);
        }

        /**
         * Allows calling a script and catching its raised exception.
         * @param tryFn the lambda to call
         * @param catchFn the lambda catching the exception
         * @param args the arguments to the lambda
         * @return the tryFn result or the catchFn if an exception was raised
         */
        public Object tryCatch(JexlScript tryFn, JexlScript catchFn, Object... args) {
            Object result;
            try {
                result = tryFn.execute(this, args);
            } catch (Throwable xthrow) {
                result = catchFn != null ? catchFn.execute(this, xthrow) : xthrow;
            }
            return result;
        }
    }

    @Test
    public void testContextualOptions1() throws Exception {
        JexlFeatures f = new JexlFeatures();
        JexlEngine jexl = new JexlBuilder().features(f).strict(true).create();
        JexlEvalContext ctxt = new TestContext();
        JexlOptions options = ctxt.getEngineOptions();
        options.setSharedInstance(true);
        options.setLexical(true);
        options.setLexicalShade(true);
        ctxt.set("options", options);
        JexlScript runner = jexl.createScript(
                "options.lexical = flag; options.lexicalShade = flag;"
              + "tryCatch(test, catch, 42);",
                "flag", "test", "catch");
        JexlScript tested = jexl.createScript("(y)->{ {var x = y;} x }");
        JexlScript catchFn = jexl.createScript("(xany)-> { xany }");
        Object result;
        // run it once, old 3.1 semantics, lexical/shade = false
        result = runner.execute(ctxt, false, tested, catchFn);
        // result 42
        Assert.assertEquals(42, result);
        // run it a second time, new 3.2 semantics, lexical/shade = true
        result = runner.execute(ctxt, true, tested, catchFn);
        // result is exception!
        Assert.assertTrue(result instanceof JexlException.Variable);
    }
    
    @Test
    public void testParameter0() throws Exception {
        String str = "function(u) {}";
        JexlEngine jexl = new JexlBuilder().create();
        JexlScript e = jexl.createScript(str);
        Assert.assertEquals(1, e.getParameters().length);
        e = jexl.createScript(new JexlInfo("TestScript", 1, 1), str);
        Assert.assertEquals(1, e.getParameters().length);
    } 
    
    @Test
    public void testParameter1() throws Exception {
        JexlEngine jexl = new JexlBuilder().strict(true).lexical(true).create();
        JexlContext jc = new MapContext();
        String strs = "var s = function(x) { for (var i : 1..3) {if (i > 2) return x}}; s(42)";
        JexlScript s42 = jexl.createScript(strs);
        Object result = s42.execute(jc);
        Assert.assertEquals(42, result);
    }
        
    @Test
    public void testInnerAccess0() throws Exception {
        JexlFeatures f = new JexlFeatures();
        f.lexical(true);
        JexlEngine jexl = new JexlBuilder().strict(true).features(f).create();
        JexlScript script = jexl.createScript("var x = 32; (()->{ for(var x : null) { var c = 0; {return x; }} })();");
    }
    
    @Test
    public void testInnerAccess1() throws Exception {
        JexlEngine jexl = new JexlBuilder().strict(true).lexical(true).create();
        JexlScript script = jexl.createScript("var x = 32; (()->{ for(var x : null) { var c = 0; {return x; }} })();");
    }
}
