/*
 * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

/* @test
 * @bug 8139885 8150824 8150825 8194238 8233920
 * @run testng/othervm -ea -esa -Xverify:all test.java.lang.invoke.TryFinallyTest
 */

package test.java.lang.invoke;

import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodHandles.Lookup;
import java.lang.invoke.MethodType;

import static java.lang.invoke.MethodType.methodType;

import static org.testng.AssertJUnit.*;

import org.testng.annotations.*;

/**
 * Tests for the tryFinally method handle combinator introduced in JEP 274.
 */
public class TryFinallyTest {

    static final Lookup LOOKUP = MethodHandles.lookup();

    @Test
    public static void testTryFinally() throws Throwable {
        MethodHandle hello = MethodHandles.tryFinally(TryFinally.MH_greet, TryFinally.MH_exclaim);
        assertEquals(TryFinally.MT_hello, hello.type());
        assertEquals("Hello, world!", hello.invoke("world"));
    }

    @DataProvider
    static Object[][] tryFinallyArgs() {
        return new Object[][] {
                { boolean.class, true },
                { byte.class, (byte) 2 },
                { short.class, (short) 2 },
                { char.class, (char) 2 },
                { int.class, 2 },
                { long.class, 2L },
                { float.class, 2f },
                { double.class, 2D },
                { Object.class, new Object() }
        };
    }

    @Test(dataProvider = "tryFinallyArgs")
    public static void testTryFinally(Class<?> argType, Object arg) throws Throwable {
        MethodHandle identity = MethodHandles.identity(argType);
        MethodHandle tryFinally = MethodHandles.tryFinally(
                identity,
                MethodHandles.dropArguments(identity, 0, Throwable.class));
        assertEquals(methodType(argType, argType), tryFinally.type());
        assertEquals(arg, tryFinally.invoke(arg));
    }

    @Test(dataProvider = "tryFinallyArgs", expectedExceptions = TryFinally.T1.class)
    public static void testTryFinallyException(Class<?> argType, Object arg) throws Throwable {
        MethodHandle identity = TryFinally.MH_throwingTargetIdentity.asType(methodType(argType, argType));
        MethodHandle tryFinally = MethodHandles.tryFinally(
                identity,
                MethodHandles.dropArguments(identity, 0, TryFinally.T1.class));
        assertEquals(methodType(argType, argType), tryFinally.type());
        tryFinally.invoke(arg); // should throw
    }

    @Test
    public static void testTryFinallyVoid() throws Throwable {
        MethodHandle tfVoid = MethodHandles.tryFinally(TryFinally.MH_print, TryFinally.MH_printMore);
        assertEquals(TryFinally.MT_printHello, tfVoid.type());
        tfVoid.invoke("world");
    }

    @Test
    public static void testTryFinallySublist() throws Throwable {
        MethodHandle helloMore = MethodHandles.tryFinally(TryFinally.MH_greetMore, TryFinally.MH_exclaimMore);
        assertEquals(TryFinally.MT_moreHello, helloMore.type());
        assertEquals("Hello, world and universe (but world first)!", helloMore.invoke("world", "universe"));
    }

    @DataProvider
    static Object[][] omitTrailingArguments() {
        MethodHandle c = TryFinally.MH_voidCleanup;
        return new Object[][]{
                {c},
                {MethodHandles.dropArguments(c, 1, int.class)},
                {MethodHandles.dropArguments(c, 1, int.class, long.class)},
                {MethodHandles.dropArguments(c, 1, int.class, long.class, Object.class, int.class)},
                {MethodHandles.dropArguments(c, 1, int.class, long.class, Object.class, int.class, long.class)}
        };
    }

    @Test(dataProvider = "omitTrailingArguments")
    public static void testTryFinallyOmitTrailingArguments(MethodHandle cleanup) throws Throwable {
        MethodHandle tf = MethodHandles.tryFinally(TryFinally.MH_dummyTarget, cleanup);
        tf.invoke(1, 2L, "a", 23, 42L, "b");
    }

    @DataProvider
    static Object[][] negativeTestData() {
        MethodHandle intid = MethodHandles.identity(int.class);
        MethodHandle intco = MethodHandles.constant(int.class, 0);
        MethodHandle errTarget = MethodHandles.dropArguments(intco, 0, int.class, double.class, String.class, int.class);
        MethodHandle errCleanup = MethodHandles.dropArguments(MethodHandles.constant(int.class, 0), 0, Throwable.class,
                int.class, double.class, Object.class);
        MethodHandle voidTarget = TryFinally.MH_voidTarget;
        MethodHandle voidICleanup = MethodHandles.dropArguments(TryFinally.MH_voidCleanup, 1, int.class);
        return new Object[][]{
                {intid, MethodHandles.identity(double.class),
                        "target and return types must match: double != int"},
                {intid, MethodHandles.dropArguments(intid, 0, String.class),
                        "cleanup first argument and Throwable must match: (String,int)int != class java.lang.Throwable"},
                {intid, MethodHandles.dropArguments(intid, 0, Throwable.class, double.class),
                        "cleanup second argument and target return type must match: (Throwable,double,int)int != int"},
                {errTarget, errCleanup,
                        "cleanup parameters after (Throwable,result) and target parameter list prefix must match: " +
                                errCleanup.type() + " != " + errTarget.type()},
                {voidTarget, voidICleanup,
                        "cleanup parameters after (Throwable,result) and target parameter list prefix must match: " +
                                voidICleanup.type() + " != " + voidTarget.type()}
        };
    }

    @Test(dataProvider = "negativeTestData")
    public static void testTryFinallyNegative(MethodHandle target, MethodHandle cleanup, String expectedMessage) {
        boolean caught = false;
        try {
            MethodHandles.tryFinally(target, cleanup);
        } catch (IllegalArgumentException iae) {
            assertEquals(expectedMessage, iae.getMessage());
            caught = true;
        }
        assertTrue(caught);
    }

    @Test
    public static void testTryFinallyThrowableCheck() {
        MethodHandle mh = MethodHandles.tryFinally(TryFinally.MH_throwingTarget,
                                                   TryFinally.MH_catchingCleanup);
        try {
            mh.invoke();
            fail("ClassCastException expected");
        } catch (Throwable t) {
            assertTrue("Throwable not assignable to ClassCastException: " + t,
                       ClassCastException.class.isAssignableFrom(t.getClass()));
        }
    }

    static class TryFinally {

        static String greet(String whom) {
            return "Hello, " + whom;
        }

        static String exclaim(Throwable t, String r, String whom) {
            return r + "!";
        }

        static void print(String what) {
            System.out.print("Hello, " + what);
        }

        static void printMore(Throwable t, String what) {
            System.out.println("!");
        }

        static String greetMore(String first, String second) {
            return "Hello, " + first + " and " + second;
        }

        static String exclaimMore(Throwable t, String r, String first) {
            return r + " (but " + first + " first)!";
        }

        static void voidTarget() {}

        static void voidCleanup(Throwable t) {}

        static class T1 extends Throwable {}

        static class T2 extends Throwable {}

        static void throwingTarget() throws Throwable {
            throw new T1();
        }

        static Object throwingTargetIdentity(Object o) throws Throwable {
            throw new T1();
        }

        static void catchingCleanup(T2 t) throws Throwable {
        }

        static final Class<TryFinally> TRY_FINALLY = TryFinally.class;

        static final MethodType MT_greet = methodType(String.class, String.class);
        static final MethodType MT_exclaim = methodType(String.class, Throwable.class, String.class, String.class);
        static final MethodType MT_print = methodType(void.class, String.class);
        static final MethodType MT_printMore = methodType(void.class, Throwable.class, String.class);
        static final MethodType MT_greetMore = methodType(String.class, String.class, String.class);
        static final MethodType MT_exclaimMore = methodType(String.class, Throwable.class, String.class, String.class);
        static final MethodType MT_voidTarget = methodType(void.class);
        static final MethodType MT_voidCleanup = methodType(void.class, Throwable.class);
        static final MethodType MT_throwingTarget = methodType(void.class);
        static final MethodType MT_throwingTargetIdentity = methodType(Object.class, Object.class);
        static final MethodType MT_catchingCleanup = methodType(void.class, T2.class);

        static final MethodHandle MH_greet;
        static final MethodHandle MH_exclaim;
        static final MethodHandle MH_print;
        static final MethodHandle MH_printMore;
        static final MethodHandle MH_greetMore;
        static final MethodHandle MH_exclaimMore;
        static final MethodHandle MH_voidTarget;
        static final MethodHandle MH_voidCleanup;
        static final MethodHandle MH_throwingTarget;
        static final MethodHandle MH_throwingTargetIdentity;
        static final MethodHandle MH_catchingCleanup;

        static final MethodHandle MH_dummyTarget;

        static final MethodType MT_hello = methodType(String.class, String.class);
        static final MethodType MT_printHello = methodType(void.class, String.class);
        static final MethodType MT_moreHello = methodType(String.class, String.class, String.class);

        static {
            try {
                MH_greet = LOOKUP.findStatic(TRY_FINALLY, "greet", MT_greet);
                MH_exclaim = LOOKUP.findStatic(TRY_FINALLY, "exclaim", MT_exclaim);
                MH_print = LOOKUP.findStatic(TRY_FINALLY, "print", MT_print);
                MH_printMore = LOOKUP.findStatic(TRY_FINALLY, "printMore", MT_printMore);
                MH_greetMore = LOOKUP.findStatic(TRY_FINALLY, "greetMore", MT_greetMore);
                MH_exclaimMore = LOOKUP.findStatic(TRY_FINALLY, "exclaimMore", MT_exclaimMore);
                MH_voidTarget = LOOKUP.findStatic(TRY_FINALLY, "voidTarget", MT_voidTarget);
                MH_voidCleanup = LOOKUP.findStatic(TRY_FINALLY, "voidCleanup", MT_voidCleanup);
                MH_throwingTarget = LOOKUP.findStatic(TRY_FINALLY, "throwingTarget", MT_throwingTarget);
                MH_throwingTargetIdentity = LOOKUP.findStatic(TRY_FINALLY, "throwingTargetIdentity", MT_throwingTargetIdentity);
                MH_catchingCleanup = LOOKUP.findStatic(TRY_FINALLY, "catchingCleanup", MT_catchingCleanup);
                MH_dummyTarget = MethodHandles.dropArguments(MH_voidTarget, 0, int.class, long.class, Object.class,
                        int.class, long.class, Object.class);
            } catch (Exception e) {
                throw new ExceptionInInitializerError(e);
            }
        }

    }

}
