/*
 * Copyright (c) 2013, 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 7087570
 * @summary REF_invokeSpecial DMHs (which are unusual) get marked explicitly; tweak the MHI to use this bit
 *
 * @run main Test7087570
 */

import java.lang.invoke.*;
import java.lang.reflect.*;
import java.util.*;

import static java.lang.invoke.MethodHandles.*;
import static java.lang.invoke.MethodType.*;
import static java.lang.invoke.MethodHandleInfo.*;

public class Test7087570 {

    private static final TestMethodData[] TESTS = new TestMethodData[] {
        // field accessors
        data(DummyFieldHolder.class, "instanceField", getterMethodType(String.class), DummyFieldHolder.class, REF_getField),
        data(DummyFieldHolder.class, "instanceField", setterMethodType(String.class), DummyFieldHolder.class, REF_putField),
        data(DummyFieldHolder.class, "staticField", getterMethodType(Integer.class), DummyFieldHolder.class, REF_getStatic),
        data(DummyFieldHolder.class, "staticField", setterMethodType(Integer.class), DummyFieldHolder.class, REF_putStatic),
        data(DummyFieldHolder.class, "instanceByteField", getterMethodType(byte.class), DummyFieldHolder.class, REF_getField),
        data(DummyFieldHolder.class, "instanceByteField", setterMethodType(byte.class), DummyFieldHolder.class, REF_putField),

        // REF_invokeVirtual
        data(Object.class, "hashCode", methodType(int.class), Object.class, REF_invokeVirtual),

        // REF_invokeVirtual strength-reduced to REF_invokeSpecial,
        // test if it normalizes back to REF_invokeVirtual in MethodHandleInfo as expected
        data(String.class, "hashCode", methodType(int.class), String.class, REF_invokeVirtual),

        // REF_invokeStatic
        data(Collections.class, "sort", methodType(void.class, List.class), Collections.class, REF_invokeStatic),
        data(Arrays.class, "asList", methodType(List.class, Object[].class), Arrays.class, REF_invokeStatic), // varargs case

        // REF_invokeSpecial
        data(Object.class, "hashCode", methodType(int.class), Object.class, REF_invokeSpecial),

        // REF_newInvokeSpecial
        data(String.class, "<init>", methodType(void.class, char[].class), String.class, REF_newInvokeSpecial),
        data(DummyFieldHolder.class, "<init>", methodType(void.class, byte.class, Long[].class), DummyFieldHolder.class, REF_newInvokeSpecial), // varargs case

        // REF_invokeInterface
        data(List.class, "size", methodType(int.class), List.class, REF_invokeInterface)
    };

    public static void main(String... args) throws Throwable {
        testWithLookup();
        testWithUnreflect();
    }

    private static void doTest(MethodHandle mh, TestMethodData testMethod) {
        MethodHandleInfo mhi = LOOKUP.revealDirect(mh);

        System.out.printf("%s.%s: %s, nominal refKind: %s, actual refKind: %s\n",
                          testMethod.clazz.getName(), testMethod.name, testMethod.methodType,
                          referenceKindToString(testMethod.referenceKind),
                          referenceKindToString(mhi.getReferenceKind()));
        assertEquals(testMethod.name,           mhi.getName());
        assertEquals(testMethod.methodType,     mhi.getMethodType());
        assertEquals(testMethod.declaringClass, mhi.getDeclaringClass());
        assertEquals(testMethod.referenceKind == REF_invokeSpecial, isInvokeSpecial(mh));
        assertRefKindEquals(testMethod.referenceKind,  mhi.getReferenceKind());
    }

    private static void testWithLookup() throws Throwable {
        for (TestMethodData testMethod : TESTS) {
            MethodHandle mh = lookupFrom(testMethod);
            doTest(mh, testMethod);
        }
    }

    private static void testWithUnreflect() throws Throwable {
        for (TestMethodData testMethod : TESTS) {
            MethodHandle mh = unreflectFrom(testMethod);
            doTest(mh, testMethod);
        }
    }

    private static MethodType getterMethodType(Class<?> clazz) {
        return methodType(clazz);
    }

    private static MethodType setterMethodType(Class<?> clazz) {
        return methodType(void.class, clazz);
    }

    private static final Lookup LOOKUP = lookup();

    private static class TestMethodData {
        final Class<?> clazz;
        final String name;
        final MethodType methodType;
        final Class<?> declaringClass;
        final int referenceKind; // the nominal refKind

        public TestMethodData(Class<?> clazz, String name,
                        MethodType methodType, Class<?> declaringClass,
                        int referenceKind) {
            this.clazz = clazz;
            this.name = name;
            this.methodType = methodType;
            this.declaringClass = declaringClass;
            this.referenceKind = referenceKind;
        }
    }

    private static TestMethodData data(Class<?> clazz, String name,
                                       MethodType methodType, Class<?> declaringClass,
                                       int referenceKind) {
        return new TestMethodData(clazz, name, methodType, declaringClass, referenceKind);
    }

    private static MethodHandle lookupFrom(TestMethodData testMethod)
            throws NoSuchMethodException, NoSuchFieldException, IllegalAccessException {
        switch (testMethod.referenceKind) {
        case REF_getField:
            return LOOKUP.findGetter(testMethod.clazz, testMethod.name, testMethod.methodType.returnType());
        case REF_putField:
            return LOOKUP.findSetter(testMethod.clazz, testMethod.name, testMethod.methodType.parameterType(0));
        case REF_getStatic:
            return LOOKUP.findStaticGetter(testMethod.clazz, testMethod.name, testMethod.methodType.returnType());
        case REF_putStatic:
            return LOOKUP.findStaticSetter(testMethod.clazz, testMethod.name, testMethod.methodType.parameterType(0));
        case REF_invokeVirtual:
        case REF_invokeInterface:
            return LOOKUP.findVirtual(testMethod.clazz, testMethod.name, testMethod.methodType);
        case REF_invokeStatic:
            return LOOKUP.findStatic(testMethod.clazz, testMethod.name, testMethod.methodType);
        case REF_invokeSpecial:
            Class<?> thisClass = LOOKUP.lookupClass();
            MethodHandle smh = LOOKUP.findSpecial(testMethod.clazz, testMethod.name, testMethod.methodType, thisClass);
            noteInvokeSpecial(smh);
            return smh;
        case REF_newInvokeSpecial:
            return LOOKUP.findConstructor(testMethod.clazz, testMethod.methodType);
        default:
            throw new Error("ERROR: unexpected referenceKind in test data");
        }
    }

    private static MethodHandle unreflectFrom(TestMethodData testMethod)
            throws NoSuchMethodException, NoSuchFieldException, IllegalAccessException {
        switch (testMethod.referenceKind) {
        case REF_getField:
        case REF_getStatic: {
                Field f = testMethod.clazz.getDeclaredField(testMethod.name);
                return LOOKUP.unreflectGetter(f);
            }
        case REF_putField:
        case REF_putStatic: {
                Field f = testMethod.clazz.getDeclaredField(testMethod.name);
                return LOOKUP.unreflectSetter(f);
            }
        case REF_invokeVirtual:
        case REF_invokeStatic:
        case REF_invokeInterface: {
                Method m = testMethod.clazz.getDeclaredMethod(testMethod.name, testMethod.methodType.parameterArray());
                return LOOKUP.unreflect(m);
            }
        case REF_invokeSpecial: {
                Method m = testMethod.clazz.getDeclaredMethod(testMethod.name, testMethod.methodType.parameterArray());
                Class<?> thisClass = LOOKUP.lookupClass();
                MethodHandle smh = LOOKUP.unreflectSpecial(m, thisClass);
                noteInvokeSpecial(smh);
                return smh;
            }
        case REF_newInvokeSpecial: {
                Constructor c = testMethod.clazz.getDeclaredConstructor(testMethod.methodType.parameterArray());
                return LOOKUP.unreflectConstructor(c);
            }
        default:
            throw new Error("ERROR: unexpected referenceKind in test data");
        }
    }

    private static List<MethodHandle> specialMethodHandles = new ArrayList<>();
    private static void noteInvokeSpecial(MethodHandle mh) {
        specialMethodHandles.add(mh);
        assert(isInvokeSpecial(mh));
    }
    private static boolean isInvokeSpecial(MethodHandle mh) {
        return specialMethodHandles.contains(mh);
    }

    private static void assertRefKindEquals(int expect, int observed) {
        if (expect == observed) return;

        String msg = "expected " + referenceKindToString(expect) +
                     " but observed " + referenceKindToString(observed);
        System.out.println("FAILED: " + msg);
        throw new AssertionError(msg);
    }

    private static void assertEquals(Object expect, Object observed) {
        if (java.util.Objects.equals(expect, observed)) return;

        String msg = "expected " + expect + " but observed " + observed;
        System.out.println("FAILED: " + msg);
        throw new AssertionError(msg);
    }
}

class DummyFieldHolder {
    public static Integer staticField;
    public String instanceField;
    public byte instanceByteField;

    public DummyFieldHolder(byte unused1, Long... unused2) {
    }
}

