/*
 * 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.cassandra.cql3.validation.entities;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

import org.junit.Test;

import org.apache.cassandra.cql3.CQLTester;
import org.apache.cassandra.cql3.functions.UDFByteCodeVerifier;
import org.apache.cassandra.cql3.validation.entities.udfverify.CallClone;
import org.apache.cassandra.cql3.validation.entities.udfverify.CallComDatastax;
import org.apache.cassandra.cql3.validation.entities.udfverify.CallFinalize;
import org.apache.cassandra.cql3.validation.entities.udfverify.CallOrgApache;
import org.apache.cassandra.cql3.validation.entities.udfverify.ClassWithField;
import org.apache.cassandra.cql3.validation.entities.udfverify.ClassWithInitializer;
import org.apache.cassandra.cql3.validation.entities.udfverify.ClassWithInitializer2;
import org.apache.cassandra.cql3.validation.entities.udfverify.ClassWithInitializer3;
import org.apache.cassandra.cql3.validation.entities.udfverify.ClassWithInnerClass;
import org.apache.cassandra.cql3.validation.entities.udfverify.ClassWithInnerClass2;
import org.apache.cassandra.cql3.validation.entities.udfverify.ClassWithStaticInitializer;
import org.apache.cassandra.cql3.validation.entities.udfverify.ClassWithStaticInnerClass;
import org.apache.cassandra.cql3.validation.entities.udfverify.GoodClass;
import org.apache.cassandra.cql3.validation.entities.udfverify.UseOfSynchronized;
import org.apache.cassandra.cql3.validation.entities.udfverify.UseOfSynchronizedWithNotify;
import org.apache.cassandra.cql3.validation.entities.udfverify.UseOfSynchronizedWithNotifyAll;
import org.apache.cassandra.cql3.validation.entities.udfverify.UseOfSynchronizedWithWait;
import org.apache.cassandra.cql3.validation.entities.udfverify.UseOfSynchronizedWithWaitL;
import org.apache.cassandra.cql3.validation.entities.udfverify.UseOfSynchronizedWithWaitLI;
import org.apache.cassandra.cql3.validation.entities.udfverify.UsingMapEntry;

import static org.junit.Assert.assertEquals;

/**
 * Test the Java UDF byte code verifier.
 */
public class UFVerifierTest extends CQLTester
{
    @Test
    public void testByteCodeVerifier()
    {
        verify(GoodClass.class);
    }

    @Test
    public void testClassWithField()
    {
        assertEquals(new HashSet<>(Collections.singletonList("field declared: field")),
                     verify(ClassWithField.class));
    }

    @Test
    public void testClassWithInitializer()
    {
        assertEquals(new HashSet<>(Arrays.asList("field declared: field",
                                                 "initializer declared")),
                     verify(ClassWithInitializer.class));
    }

    @Test
    public void testClassWithInitializer2()
    {
        assertEquals(new HashSet<>(Arrays.asList("field declared: field",
                                                 "initializer declared")),
                     verify(ClassWithInitializer2.class));
    }

    @Test
    public void testClassWithInitializer3()
    {
        assertEquals(new HashSet<>(Collections.singletonList("initializer declared")),
                     verify(ClassWithInitializer3.class));
    }

    @Test
    public void testClassWithStaticInitializer()
    {
        assertEquals(new HashSet<>(Collections.singletonList("static initializer declared")),
                     verify(ClassWithStaticInitializer.class));
    }

    @Test
    public void testUseOfSynchronized()
    {
        assertEquals(new HashSet<>(Collections.singletonList("use of synchronized")),
                     verify(UseOfSynchronized.class));
    }

    @Test
    public void testUseOfSynchronizedWithNotify()
    {
        assertEquals(new HashSet<>(Arrays.asList("use of synchronized", "call to java.lang.Object.notify()")),
                     verify(UseOfSynchronizedWithNotify.class));
    }

    @Test
    public void testUseOfSynchronizedWithNotifyAll()
    {
        assertEquals(new HashSet<>(Arrays.asList("use of synchronized", "call to java.lang.Object.notifyAll()")),
                     verify(UseOfSynchronizedWithNotifyAll.class));
    }

    @Test
    public void testUseOfSynchronizedWithWait()
    {
        assertEquals(new HashSet<>(Arrays.asList("use of synchronized", "call to java.lang.Object.wait()")),
                     verify(UseOfSynchronizedWithWait.class));
    }

    @Test
    public void testUseOfSynchronizedWithWaitL()
    {
        assertEquals(new HashSet<>(Arrays.asList("use of synchronized", "call to java.lang.Object.wait()")),
                     verify(UseOfSynchronizedWithWaitL.class));
    }

    @Test
    public void testUseOfSynchronizedWithWaitI()
    {
        assertEquals(new HashSet<>(Arrays.asList("use of synchronized", "call to java.lang.Object.wait()")),
                     verify(UseOfSynchronizedWithWaitLI.class));
    }

    @Test
    public void testCallClone()
    {
        assertEquals(new HashSet<>(Collections.singletonList("call to java.lang.Object.clone()")),
                     verify(CallClone.class));
    }

    @Test
    public void testCallFinalize()
    {
        assertEquals(new HashSet<>(Collections.singletonList("call to java.lang.Object.finalize()")),
                     verify(CallFinalize.class));
    }

    @Test
    public void testCallComDatastax()
    {
        assertEquals(new HashSet<>(Collections.singletonList("call to com.datastax.driver.core.DataType.cint()")),
                     verify("com/", CallComDatastax.class));
    }

    @Test
    public void testCallOrgApache()
    {
        assertEquals(new HashSet<>(Collections.singletonList("call to org.apache.cassandra.config.DatabaseDescriptor.getClusterName()")),
                     verify("org/", CallOrgApache.class));
    }

    @Test
    public void testClassStaticInnerClass()
    {
        assertEquals(new HashSet<>(Collections.singletonList("class declared as inner class")),
                     verify(ClassWithStaticInnerClass.class));
    }

    @Test
    public void testUsingMapEntry()
    {
        assertEquals(Collections.emptySet(),
                     verify(UsingMapEntry.class));
    }

    @Test
    public void testClassInnerClass()
    {
        assertEquals(new HashSet<>(Collections.singletonList("class declared as inner class")),
                     verify(ClassWithInnerClass.class));
    }

    @Test
    public void testClassInnerClass2()
    {
        assertEquals(Collections.emptySet(),
                     verify(ClassWithInnerClass2.class));
    }

    private Set<String> verify(Class cls)
    {
        return new UDFByteCodeVerifier().verify(cls.getName(), readClass(cls));
    }

    private Set<String> verify(String disallowedPkg, Class cls)
    {
        return new UDFByteCodeVerifier().addDisallowedPackage(disallowedPkg).verify(cls.getName(), readClass(cls));
    }

    @SuppressWarnings("resource")
    private static byte[] readClass(Class<?> clazz)
    {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        URL res = clazz.getClassLoader().getResource(clazz.getName().replace('.', '/') + ".class");
        assert res != null;
        try (InputStream input = res.openConnection().getInputStream())
        {
            int i;
            while ((i = input.read()) != -1)
                out.write(i);
            return out.toByteArray();
        }
        catch (IOException e)
        {
            throw new RuntimeException(e);
        }
    }

    @Test
    public void testInvalidByteCodeUDFs() throws Throwable
    {
        assertInvalidByteCode("try\n" +
                              "{\n" +
                              "    clone();\n" +
                              "}\n" +
                              "catch (CloneNotSupportedException e)\n" +
                              "{\n" +
                              "    throw new RuntimeException(e);\n" +
                              "}\n" +
                              "return 0d;", "Java UDF validation failed: [call to java.lang.Object.clone()]");
        assertInvalidByteCode("try\n" +
                              "{\n" +
                              "    finalize();\n" +
                              "}\n" +
                              "catch (Throwable e)\n" +
                              "{\n" +
                              "    throw new RuntimeException(e);\n" +
                              "}\n" +
                              "return 0d;", "Java UDF validation failed: [call to java.lang.Object.finalize()]");
        assertInvalidByteCode('\n' +
                              "return 0d;\n" +
                              "    }\n" +
                              '\n' +
                              "    Object field;\n" +
                              '\n' +
                              "    {", "Java UDF validation failed: [field declared: field]");
        assertInvalidByteCode('\n' +
                              "return 0d;\n" +
                              "    }\n" +
                              '\n' +
                              "    final Object field;\n" +
                              '\n' +
                              "    {\n" +
                              "field = new Object();", "Java UDF validation failed: [field declared: field, initializer declared]");
        assertInvalidByteCode('\n' +
                              "return 0d;\n" +
                              "    }\n" +
                              '\n' +
                              "    Object field = new Object();\n" +
                              '\n' +
                              "    {\n" +
                              "Math.sin(1d);", "Java UDF validation failed: [field declared: field, initializer declared]");
        assertInvalidByteCode('\n' +
                              "return 0d;\n" +
                              "    }\n" +
                              '\n' +
                              "    {\n" +
                              "Math.sin(1d);", "Java UDF validation failed: [initializer declared]");
        assertInvalidByteCode('\n' +
                              "return 0d;\n" +
                              "    }\n" +
                              '\n' +
                              "    static\n" +
                              "    {\n" +
                              "Math.sin(1d);", "Java UDF validation failed: [static initializer declared]");
        assertInvalidByteCode("synchronized (this)\n" +
                              "{\n" +
                              "    Math.sin(1d);\n" +
                              "}\n" +
                              "return 0d;", "Java UDF validation failed: [use of synchronized]");
        assertInvalidByteCode("synchronized (this)\n" +
                              "{\n" +
                              "    notify();\n" +
                              "}\n" +
                              "return 0d;", "Java UDF validation failed: [call to java.lang.Object.notify(), use of synchronized]");
        assertInvalidByteCode("synchronized (this)\n" +
                              "{\n" +
                              "    notifyAll();\n" +
                              "}\n" +
                              "return 0d;", "Java UDF validation failed: [call to java.lang.Object.notifyAll(), use of synchronized]");
        assertInvalidByteCode("synchronized (this)\n" +
                              "{\n" +
                              "    try\n" +
                              "    {\n" +
                              "        wait();\n" +
                              "    }\n" +
                              "    catch (InterruptedException e)\n" +
                              "    {\n" +
                              "        throw new RuntimeException(e);\n" +
                              "    }\n" +
                              "}\n" +
                              "return 0d;", "Java UDF validation failed: [call to java.lang.Object.wait(), use of synchronized]");
        assertInvalidByteCode("synchronized (this)\n" +
                              "{\n" +
                              "    try\n" +
                              "    {\n" +
                              "        wait(1000L);\n" +
                              "    }\n" +
                              "    catch (InterruptedException e)\n" +
                              "    {\n" +
                              "        throw new RuntimeException(e);\n" +
                              "    }\n" +
                              "}\n" +
                              "return 0d;", "Java UDF validation failed: [call to java.lang.Object.wait(), use of synchronized]");
        assertInvalidByteCode("synchronized (this)\n" +
                              "{\n" +
                              "    try\n" +
                              "    {\n" +
                              "        wait(1000L, 100);\n" +
                              "    }\n" +
                              "    catch (InterruptedException e)\n" +
                              "    {\n" +
                              "        throw new RuntimeException(e);\n" +
                              "    }\n" +
                              "}\n" +
                              "return 0d;", "Java UDF validation failed: [call to java.lang.Object.wait(), use of synchronized]");
        assertInvalidByteCode("try {" +
                              "     java.nio.ByteBuffer.allocateDirect(123); return 0d;" +
                              "} catch (Exception t) {" +
                              "     throw new RuntimeException(t);" +
                              '}', "Java UDF validation failed: [call to java.nio.ByteBuffer.allocateDirect()]");
        assertInvalidByteCode("try {" +
                              "     java.net.InetAddress.getLocalHost(); return 0d;" +
                              "} catch (Exception t) {" +
                              "     throw new RuntimeException(t);" +
                              '}', "Java UDF validation failed: [call to java.net.InetAddress.getLocalHost()]");
        assertInvalidByteCode("try {" +
                              "     java.net.InetAddress.getAllByName(\"localhost\"); return 0d;" +
                              "} catch (Exception t) {" +
                              "     throw new RuntimeException(t);" +
                              '}', "Java UDF validation failed: [call to java.net.InetAddress.getAllByName()]");
        assertInvalidByteCode("try {" +
                              "     java.net.Inet4Address.getByName(\"127.0.0.1\"); return 0d;" +
                              "} catch (Exception t) {" +
                              "     throw new RuntimeException(t);" +
                              '}', "Java UDF validation failed: [call to java.net.Inet4Address.getByName()]");
        assertInvalidByteCode("try {" +
                              "     java.net.Inet6Address.getByAddress(new byte[]{127,0,0,1}); return 0d;" +
                              "} catch (Exception t) {" +
                              "     throw new RuntimeException(t);" +
                              '}', "Java UDF validation failed: [call to java.net.Inet6Address.getByAddress()]");
        assertInvalidByteCode("try {" +
                              "     java.net.NetworkInterface.getNetworkInterfaces(); return 0d;" +
                              "} catch (Exception t) {" +
                              "     throw new RuntimeException(t);" +
                              '}', "Java UDF validation failed: [call to java.net.NetworkInterface.getNetworkInterfaces()]");
    }

    private void assertInvalidByteCode(String body, String error) throws Throwable
    {
        assertInvalidMessage(error,
                             "CREATE FUNCTION " + KEYSPACE + ".mustBeInvalid ( input double ) " +
                             "CALLED ON NULL INPUT " +
                             "RETURNS double " +
                             "LANGUAGE java AS $$" + body + "$$");
    }
}
