/*
 * 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.tinkerpop.gremlin.groovy.jsr223;

import groovy.lang.Closure;
import groovy.lang.MissingMethodException;
import groovy.lang.MissingPropertyException;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.commons.lang3.concurrent.BasicThreadFactory;
import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
import org.apache.tinkerpop.gremlin.process.traversal.step.filter.HasStep;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.SubgraphStrategy;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.verification.ReadOnlyStrategy;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.verification.VerificationException;
import org.apache.tinkerpop.gremlin.structure.util.empty.EmptyGraph;
import org.apache.tinkerpop.gremlin.util.function.Lambda;
import org.javatuples.Pair;
import org.junit.Test;

import javax.script.Bindings;
import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptException;
import javax.script.SimpleBindings;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.IntStream;

import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.hasLabel;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.Is.is;
import static org.hamcrest.core.IsInstanceOf.instanceOf;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

/**
 * @author Stephen Mallette (http://stephen.genoprime.com)
 */
public class GremlinGroovyScriptEngineTest {
    private static final Object[] EMPTY_ARGS = new Object[0];

    @Test
    public void shouldNotCacheGlobalFunctions() throws Exception {
        final GremlinGroovyScriptEngine engine = new GremlinGroovyScriptEngine(CompilationOptionsCustomizer.build().
                enableGlobalFunctionCache(false).create());

        assertEquals(3, engine.eval("def addItUp(x,y){x+y};addItUp(1,2)"));

        try {
            engine.eval("addItUp(1,2)");
            fail("Global functions should not be cached so the call to addItUp() should fail");
        } catch (Exception ex) {
            final Throwable root = ExceptionUtils.getRootCause(ex);
            assertThat(root, instanceOf(MissingMethodException.class));
        }
    }

    @Test
    public void shouldCompileScriptWithoutRequiringVariableBindings() throws Exception {
        // compile() should cache the script to avoid future compilation
        final GremlinGroovyScriptEngine engine = new GremlinGroovyScriptEngine();

        final String script = "g.V(x).out()";
        assertFalse(engine.isCached(script));
        assertNotNull(engine.compile(script));
        assertTrue(engine.isCached(script));

        engine.reset();

        assertFalse(engine.isCached(script));
    }

    @Test
    public void shouldEvalWithNoBindings() throws Exception {
        final GremlinGroovyScriptEngine engine = new GremlinGroovyScriptEngine();
        engine.eval("def addItUp(x,y){x+y}");
        assertEquals(3, engine.eval("1+2"));
        assertEquals(3, engine.eval("addItUp(1,2)"));
    }

    @Test
    public void shouldPromoteDefinedVarsInInterpreterModeWithNoBindings() throws Exception {
        final GremlinGroovyScriptEngine engine = new GremlinGroovyScriptEngine(new InterpreterModeGroovyCustomizer());
        engine.eval("def addItUp = { x, y -> x + y }");
        engine.eval("def class A { def sub(int x, int y) {x - y}}");
        assertEquals(3, engine.eval("int xxx = 1 + 2"));
        assertEquals(4, engine.eval("yyy = xxx + 1"));
        assertEquals(7, engine.eval("def zzz = yyy + xxx"));
        assertEquals(4, engine.eval("zzz - xxx"));
        assertEquals("accessible-globally", engine.eval("if (yyy > 0) { def inner = 'should-stay-local'; outer = 'accessible-globally' }\n outer"));
        assertEquals("accessible-globally", engine.eval("outer"));

        try {
            engine.eval("inner");
            fail("Should not have been able to access 'inner'");
        } catch (Exception ex) {
            final Throwable root = ExceptionUtils.getRootCause(ex);
            assertThat(root, instanceOf(MissingPropertyException.class));
        }

        assertEquals(9, engine.eval("new A().sub(10, 1)"));
        assertEquals(10, engine.eval("addItUp(zzz,xxx)"));
    }

    @Test
    public void shouldPromoteDefinedVarsInInterpreterModeWithBindings() throws Exception {
        final GremlinGroovyScriptEngine engine = new GremlinGroovyScriptEngine(new InterpreterModeGroovyCustomizer());
        final Bindings b = new SimpleBindings();
        b.put("x", 2);
        engine.eval("def addItUp = { x, y -> x + y }", b);
        assertEquals(3, engine.eval("int xxx = 1 + x", b));
        assertEquals(4, engine.eval("yyy = xxx + 1", b));
        assertEquals(7, engine.eval("def zzz = yyy + xxx", b));
        assertEquals(4, engine.eval("zzz - xxx", b));
        assertEquals("accessible-globally", engine.eval("if (yyy > 0) { def inner = 'should-stay-local'; outer = 'accessible-globally' }\n outer", b));
        assertEquals("accessible-globally", engine.eval("outer", b));

        try {
            engine.eval("inner", b);
            fail("Should not have been able to access 'inner'");
        } catch (Exception ex) {
            final Throwable root = ExceptionUtils.getRootCause(ex);
            assertThat(root, instanceOf(MissingPropertyException.class));
        }

        assertEquals(10, engine.eval("addItUp(zzz,xxx)", b));
    }

    @Test
    public void shouldEvalWithBindings() throws Exception {
        final GremlinGroovyScriptEngine engine = new GremlinGroovyScriptEngine();
        final Bindings b = new SimpleBindings();
        b.put("x", 2);
        assertEquals(3, engine.eval("1+x", b));
    }

    @Test
    public void shouldEvalWithNullInBindings() throws Exception {
        final GremlinGroovyScriptEngine engine = new GremlinGroovyScriptEngine();
        final Bindings b = new SimpleBindings();
        b.put("x", null);
        assertNull(engine.eval("x", b));
    }

    @Test
    public void shouldEvalSuccessfulAssert() throws Exception {
        final GremlinGroovyScriptEngine engine = new GremlinGroovyScriptEngine();
        assertNull(engine.eval("assert 1==1"));
    }

    @Test(expected = AssertionError.class)
    public void shouldEvalFailingAssert() throws Exception {
        final GremlinGroovyScriptEngine engine = new GremlinGroovyScriptEngine();
        engine.eval("assert 1==0");
    }

    @Test
    public void shouldClearEngineScopeOnReset() throws Exception {
        final GremlinGroovyScriptEngine engine = new GremlinGroovyScriptEngine();
        engine.eval("x = { y -> y + 1}");
        Bindings b = engine.getContext().getBindings(ScriptContext.ENGINE_SCOPE);
        assertTrue(b.containsKey("x"));
        assertEquals(2, ((Closure) b.get("x")).call(1));

        // should clear the bindings
        engine.reset();
        try {
            engine.eval("x(1)");
            fail("Bindings should have been cleared.");
        } catch (Exception ex) {
            // do nothing = expected
        }

        b = engine.getContext().getBindings(ScriptContext.ENGINE_SCOPE);
        assertFalse(b.containsKey("x"));

        // redefine x
        engine.eval("x = { y -> y + 2}");
        assertEquals(3, engine.eval("x(1)"));
        b = engine.getContext().getBindings(ScriptContext.ENGINE_SCOPE);
        assertTrue(b.containsKey("x"));
        assertEquals(3, ((Closure) b.get("x")).call(1));
    }

    @Test
    public void shouldResetClassLoader() throws Exception {
        final GremlinGroovyScriptEngine scriptEngine = new GremlinGroovyScriptEngine();
        try {
            scriptEngine.eval("addOne(1)");
            fail("Should have tossed ScriptException since addOne is not yet defined.");
        } catch (ScriptException se) {
            // do nothing = expected
        }

        // validate that the addOne function works
        scriptEngine.eval("addOne = { y-> y + 1}");
        assertEquals(2, scriptEngine.eval("addOne(1)"));

        // reset the script engine which should blow out the addOne function that's there.
        scriptEngine.reset();

        try {
            scriptEngine.eval("addOne(1)");
            fail("Should have tossed ScriptException since addOne is no longer defined after reset.");
        } catch (ScriptException se) {
            // do nothing = expected
        }
    }

    @Test
    public void shouldProcessScriptWithUTF8Characters() throws Exception {
        final ScriptEngine engine = new GremlinGroovyScriptEngine();
        assertEquals("轉注", engine.eval("'轉注'"));
    }

    @Test
    public void shouldAllowVariableReuseAcrossThreads() throws Exception {
        final BasicThreadFactory testingThreadFactory = new BasicThreadFactory.Builder().namingPattern("test-gremlin-scriptengine-%d").build();
        final ExecutorService service = Executors.newFixedThreadPool(8, testingThreadFactory);
        final GremlinGroovyScriptEngine scriptEngine = new GremlinGroovyScriptEngine();

        final AtomicBoolean failed = new AtomicBoolean(false);
        final int max = 512;
        final List<Pair<Integer, List<Integer>>> futures = Collections.synchronizedList(new ArrayList<>(max));
        IntStream.range(0, max).forEach(i -> {
            final int yValue = i * 2;
            final int zValue = i * -1;
            final Bindings b = new SimpleBindings();
            b.put("x", i);
            b.put("y", yValue);

            final String script = "z=" + zValue + ";[x,y,z]";
            try {
                service.submit(() -> {
                    try {
                        final List<Integer> result = (List<Integer>) scriptEngine.eval(script, b);
                        futures.add(Pair.with(i, result));
                    } catch (Exception ex) {
                        failed.set(true);
                    }
                });
            } catch (Exception ex) {
                throw new RuntimeException(ex);
            }
        });

        service.shutdown();
        assertThat(service.awaitTermination(120000, TimeUnit.MILLISECONDS), is(true));

        // likely a concurrency exception if it occurs - and if it does then we've messed up because that's what this
        // test is partially designed to protected against.
        assertThat(failed.get(), is(false));
        assertEquals(max, futures.size());
        futures.forEach(t -> {
            assertEquals(t.getValue0(), t.getValue1().get(0));
            assertEquals(t.getValue0() * 2, t.getValue1().get(1).intValue());
            assertEquals(t.getValue0() * -1, t.getValue1().get(2).intValue());
        });
    }

    @Test
    public void shouldInvokeFunctionRedirectsOutputToContextWriter() throws Exception {
        final GremlinGroovyScriptEngine engine = new GremlinGroovyScriptEngine();
        StringWriter writer = new StringWriter();
        engine.getContext().setWriter(writer);

        final String code = "def myFunction() { print \"Hello World!\" }";
        engine.eval(code);
        engine.invokeFunction("myFunction", EMPTY_ARGS);
        assertEquals("Hello World!", writer.toString());

        writer = new StringWriter();
        final StringWriter writer2 = new StringWriter();
        engine.getContext().setWriter(writer2);
        engine.invokeFunction("myFunction", EMPTY_ARGS);
        assertEquals("", writer.toString());
        assertEquals("Hello World!", writer2.toString());
    }

    @Test
    public void shouldInvokeFunctionRedirectsOutputToContextOut() throws Exception {
        final GremlinGroovyScriptEngine  engine = new GremlinGroovyScriptEngine();
        StringWriter writer = new StringWriter();
        final StringWriter unusedWriter = new StringWriter();
        engine.getContext().setWriter(unusedWriter);
        engine.put("out", writer);

        final String code = "def myFunction() { print \"Hello World!\" }";
        engine.eval(code);
        engine.invokeFunction("myFunction", EMPTY_ARGS);
        assertEquals("", unusedWriter.toString());
        assertEquals("Hello World!", writer.toString());

        writer = new StringWriter();
        final StringWriter writer2 = new StringWriter();
        engine.put("out", writer2);
        engine.invokeFunction("myFunction", EMPTY_ARGS);
        assertEquals("", unusedWriter.toString());
        assertEquals("", writer.toString());
        assertEquals("Hello World!", writer2.toString());
    }

    @Test
    public void shouldEnableEngineContextAccessibleToScript() throws Exception {
        final GremlinGroovyScriptEngine  engine = new GremlinGroovyScriptEngine();
        final ScriptContext engineContext = engine.getContext();
        engine.put("theEngineContext", engineContext);
        final String code = "[answer: theEngineContext.is(context)]";
        assertThat(((Map) engine.eval(code)).get("answer"), is(true));
    }

    @Test
    public void shouldEnableContextBindingOverridesEngineContext() throws Exception {
        final GremlinGroovyScriptEngine  engine = new GremlinGroovyScriptEngine();
        final ScriptContext engineContext = engine.getContext();
        final Map<String,Object> otherContext = new HashMap<>();
        otherContext.put("foo", "bar");
        engine.put("context", otherContext);
        engine.put("theEngineContext", engineContext);
        final String code = "[answer: context.is(theEngineContext) ? \"wrong\" : context.foo]";
        assertEquals("bar", ((Map) engine.eval(code)).get("answer"));
    }

    @Test
    public void shouldGetClassMapCacheBasicStats() throws Exception {
        final GremlinGroovyScriptEngine  engine = new GremlinGroovyScriptEngine();
        assertEquals(0, engine.getClassCacheEstimatedSize());
        assertEquals(0, engine.getClassCacheHitCount());
        assertEquals(0, engine.getClassCacheLoadCount());
        assertEquals(0, engine.getClassCacheLoadFailureCount());
        assertEquals(0, engine.getClassCacheLoadSuccessCount());

        engine.eval("1+1");

        assertEquals(1, engine.getClassCacheEstimatedSize());
        assertEquals(0, engine.getClassCacheHitCount());
        assertEquals(1, engine.getClassCacheLoadCount());
        assertEquals(0, engine.getClassCacheLoadFailureCount());
        assertEquals(1, engine.getClassCacheLoadSuccessCount());

        for (int ix = 0; ix < 100; ix++) {
            engine.eval("1+1");
        }

        assertEquals(1, engine.getClassCacheEstimatedSize());
        assertEquals(100, engine.getClassCacheHitCount());
        assertEquals(1, engine.getClassCacheLoadCount());
        assertEquals(0, engine.getClassCacheLoadFailureCount());
        assertEquals(1, engine.getClassCacheLoadSuccessCount());

        for (int ix = 0; ix < 100; ix++) {
            engine.eval("1+" + ix);
        }

        assertEquals(100, engine.getClassCacheEstimatedSize());
        assertEquals(101, engine.getClassCacheHitCount());
        assertEquals(100, engine.getClassCacheLoadCount());
        assertEquals(0, engine.getClassCacheLoadFailureCount());
        assertEquals(100, engine.getClassCacheLoadSuccessCount());

        try {
            engine.eval("(me broken");
            fail("Should have tanked with compilation error");
        } catch (Exception ex) {
            assertThat(ex, instanceOf(ScriptException.class));
        }

        assertEquals(101, engine.getClassCacheEstimatedSize());
        assertEquals(101, engine.getClassCacheHitCount());
        assertEquals(101, engine.getClassCacheLoadCount());
        assertEquals(1, engine.getClassCacheLoadFailureCount());
        assertEquals(100, engine.getClassCacheLoadSuccessCount());

        try {
            engine.eval("(me broken");
            fail("Should have tanked with compilation error");
        } catch (Exception ex) {
            assertThat(ex, instanceOf(ScriptException.class));
        }

        assertEquals(101, engine.getClassCacheEstimatedSize());
        assertEquals(102, engine.getClassCacheHitCount());
        assertEquals(101, engine.getClassCacheLoadCount());
        assertEquals(1, engine.getClassCacheLoadFailureCount());
        assertEquals(100, engine.getClassCacheLoadSuccessCount());
    }

    @Test
    public void shouldEvalForLambda() throws Exception {
        // https://issues.apache.org/jira/browse/TINKERPOP-1953
        final GremlinGroovyScriptEngine engine = new GremlinGroovyScriptEngine();
        final Lambda l = (Lambda) engine.eval(" org.apache.tinkerpop.gremlin.util.function.Lambda.function(\"{ it.get() }\")");
        assertEquals("{ it.get() }", l.getLambdaScript());
    }

    @Test
    public void shouldAllowGroovySyntaxForStrategies() throws Exception {
        final GremlinGroovyScriptEngine engine = new GremlinGroovyScriptEngine();
        final GraphTraversalSource g = EmptyGraph.instance().traversal();

        final Bindings b = new SimpleBindings();
        b.put("g", g);

        Traversal t = (Traversal) engine.eval("g.withStrategies(ReadOnlyStrategy).V()", b);
        Optional<ReadOnlyStrategy> ro = t.asAdmin().getStrategies().getStrategy(ReadOnlyStrategy.class);
        assertThat(ro.isPresent(), is(true));
        assertEquals(ReadOnlyStrategy.instance(), ro.get());

        t = (Traversal) engine.eval("g.withStrategies(new SubgraphStrategy(vertices: __.hasLabel(\"person\"))).V()", b);
        Optional<SubgraphStrategy> ss = t.asAdmin().getStrategies().getStrategy(SubgraphStrategy.class);
        assertThat(ss.isPresent(), is(true));
        assertEquals(HasStep.class, ss.get().getVertexCriterion().asAdmin().getStartStep().getClass());

        t = (Traversal) engine.eval("g.withStrategies(ReadOnlyStrategy, new SubgraphStrategy(vertices: __.hasLabel(\"person\"))).V()", b);
        ro = t.asAdmin().getStrategies().getStrategy(ReadOnlyStrategy.class);
        assertThat(ro.isPresent(), is(true));
        assertEquals(ReadOnlyStrategy.instance(), ro.get());
        ss = t.asAdmin().getStrategies().getStrategy(SubgraphStrategy.class);
        assertThat(ss.isPresent(), is(true));
        assertEquals(HasStep.class, ss.get().getVertexCriterion().asAdmin().getStartStep().getClass());
    }
}