/*
 * Copyright (c) 2021, 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 8013527
 * @run testng/othervm ChainedLookupTest
 * @summary Test MethodHandles.lookup method to produce the Lookup object with
 *          proper lookup class if invoked through reflection and method handle.
 */

import java.lang.invoke.*;
import java.lang.invoke.MethodHandles.Lookup;
import java.lang.reflect.Method;

import org.testng.annotations.Test;

import static java.lang.invoke.MethodHandles.*;
import static java.lang.invoke.MethodType.*;
import static org.testng.Assert.*;

public class ChainedLookupTest {
    /**
     * Direct call to MethodHandles::lookup
     */
    @Test
    public void staticLookup() throws Throwable {
        Lookup lookup =  lookup();
        test(lookup, "Lookup produced via direct call to MethodHandles.lookup()");
    }

    /**
     * Reflective Method::invoke on MethodHandles::lookup
     */
    @Test
    public void methodInvoke() throws Throwable {
        Method m =  MethodHandles.class.getMethod("lookup");
        Lookup lookup = (Lookup) m.invoke(null);
        test(lookup, "Lookup produced via reflective call");
    }

    /**
     * Invoke Method::invoke on MethodHandles::lookup via MethodHandle
     */
    @Test
    public void methodInvokeViaMethodHandle() throws Throwable {
        Method m =  MethodHandles.class.getMethod("lookup");

        MethodHandle mh = lookup().findVirtual(Method.class, "invoke",
                                               methodType(Object.class, Object.class, Object[].class));
        Lookup lookup = (Lookup)mh.invoke(m, (Object)null, (Object[])null);
        test(lookup, "Lookup produced via Method::invoke via MethodHandle");
    }

    /**
     * Invoke MethodHandle on MethodHandles::lookup via Method::invoke
     */
    // @Test
    public void methodHandleViaReflection() throws Throwable {
        MethodHandle MH_lookup = lookup().findStatic(MethodHandles.class, "lookup", methodType(Lookup.class));
        Lookup lookup = (Lookup) MH_lookup.invokeExact();

        Method m =  MethodHandle.class.getMethod("invoke", Object[].class);

        // should this throw UnsupportedOperationException per MethodHandle::invoke spec?
        lookup = (Lookup)m.invoke(MH_lookup);
        test(lookup, "Lookup produced via MethodHandle::invoke via Method::invoke");
    }

    /**
     * MethodHandle::invokeExact on MethodHandles::lookup
     */
    @Test
    public void methodHandle() throws Throwable {
        MethodHandle MH_lookup = lookup().findStatic(MethodHandles.class, "lookup", methodType(Lookup.class));
        Lookup lookup = (Lookup) MH_lookup.invokeExact();
        test(lookup, "Lookup produced via MethodHandle");
    }

    /**
     * MethodHandles::unreflect the reflective Method representing MethodHandles::lookup
     */
    @Test
    public void unreflect() throws Throwable {
        MethodHandle MH_lookup = lookup().unreflect(MethodHandles.class.getMethod("lookup"));
        Lookup lookup = (Lookup) MH_lookup.invokeExact();
        test(lookup, "Lookup produced via unreflect MethodHandle");
    }

    /**
     * Use the Lookup object returned from MethodHandle::invokeExact on MethodHandles::lookup
     * to look up MethodHandle representing MethodHandles::lookup and then invoking it.
     */
    @Test
    public void chainedMethodHandle() throws Throwable {
        MethodHandle MH_lookup = lookup().findStatic(MethodHandles.class, "lookup", methodType(Lookup.class));
        Lookup lookup = (Lookup) MH_lookup.invokeExact();
        MethodHandle MH_lookup2 = lookup.unreflect(MethodHandles.class.getMethod("lookup"));
        Lookup lookup2 = (Lookup) MH_lookup2.invokeExact();
        test(lookup2, "Lookup produced via a chained call to MethodHandle");
    }

    void test(Lookup lookup, String msg) throws Throwable {
        assertTrue(lookup.lookupClass() == ChainedLookupTest.class);
        assertTrue(lookup.hasFullPrivilegeAccess());

        MethodHandle mh = lookup.findStatic(lookup.lookupClass(), "say", methodType(void.class, String.class));
        mh.invokeExact(msg);
    }

    private static void say(String msg) {
        System.out.println(msg);
    }
}

