/*
 * Copyright (c) 2017, 2022, 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     8074977
 * @summary Test consistency of annotations on constructor parameters
 * @compile             TestConstructorParameterAnnotations.java
 * @run main            TestConstructorParameterAnnotations
 * @compile -parameters TestConstructorParameterAnnotations.java
 * @run main            TestConstructorParameterAnnotations
 */

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

/*
 * Some constructor parameters are <em>mandated</em>; that is, they
 * are not explicitly present in the source code, but required to be
 * present by the Java Language Specification. In other cases, some
 * constructor parameters are not present in the source, but are
 * synthesized by the compiler as an implementation artifact. There is
 * not a reliable mechanism to consistently determine whether or not
 * a parameter is implicit or not.
 *
 * (Using the "-parameters" option to javac does emit the information
 * needed to make a reliably determination, but the information is not
 * present by default.)
 *
 * The lack of such a mechanism causes complications reading parameter
 * annotations in some cases since annotations for parameters are
 * written out for the parameters in the source code, but when reading
 * annotations at runtime all the parameters, including implicit ones,
 * are present.
 */
public class TestConstructorParameterAnnotations {
    public static void main(String... args) {
        int errors = 0;
        Class<?>[] classes = {NestedClass0.class,
                              NestedClass1.class,
                              NestedClass2.class,
                              NestedClass3.class,
                              NestedClass4.class,
                              StaticNestedClass0.class,
                              StaticNestedClass1.class,
                              StaticNestedClass2.class,
                              StaticNestedClass3.class,
                              StaticNestedClass4.class};

        for (Class<?> clazz : classes) {
            for (Constructor<?> ctor : clazz.getConstructors()) {
                System.out.println(ctor);
                errors += checkGetParameterAnnotations(clazz, ctor);
                errors += checkGetParametersGetAnnotation(clazz, ctor);
            }
        }

        if (errors > 0)
            throw new RuntimeException(errors + " errors.");
        return;
    }

    private static int checkGetParameterAnnotations(Class<?> clazz,
                                                    Constructor<?> ctor) {
        String annotationString =
            Arrays.deepToString(ctor.getParameterAnnotations());
        String expectedString =
            clazz.getAnnotation(ExpectedGetParameterAnnotations.class).value();

        if (!Objects.equals(annotationString, expectedString)) {
            System.err.println("Annotation mismatch on " + ctor +
                               "\n\tExpected:" + expectedString +
                               "\n\tActual:  " + annotationString);
            return 1;
        }
        return 0;
    }

    private static int checkGetParametersGetAnnotation(Class<?> clazz,
                                                       Constructor<?> ctor) {
        int errors = 0;
        int i = 0;
        ExpectedParameterAnnotations epa =
            clazz.getAnnotation(ExpectedParameterAnnotations.class);

        for (Parameter param : ctor.getParameters() ) {
            String annotationString =
                Objects.toString(param.getAnnotation(MarkerAnnotation.class));
            String expectedString = epa.value()[i];

            if (!Objects.equals(annotationString, expectedString)) {
                System.err.println("Annotation mismatch on " + ctor +
                                   " on param " + param +
                                   "\n\tExpected:" + expectedString +
                                   "\n\tActual:  " + annotationString);
                errors++;
            }
            i++;
        }
        return errors;
    }

    @ExpectedGetParameterAnnotations("[[]]")
    @ExpectedParameterAnnotations({"null"})
    public class NestedClass0 {
        public NestedClass0() {}
    }

    @ExpectedGetParameterAnnotations(
        "[[], " +
        "[@TestConstructorParameterAnnotations.MarkerAnnotation(1)]]")
    @ExpectedParameterAnnotations({
        "null",
        "@TestConstructorParameterAnnotations.MarkerAnnotation(1)"})
    public class NestedClass1 {
        public NestedClass1(@MarkerAnnotation(1) int parameter) {}
    }

    @ExpectedGetParameterAnnotations(
        "[[], " +
        "[@TestConstructorParameterAnnotations.MarkerAnnotation(2)], " +
        "[]]")
    @ExpectedParameterAnnotations({
        "null",
        "@TestConstructorParameterAnnotations.MarkerAnnotation(2)",
        "null"})
    public class NestedClass2 {
        public NestedClass2(@MarkerAnnotation(2) int parameter1,
                            int parameter2) {}
    }

    @ExpectedGetParameterAnnotations(
        "[[], " +
        "[@TestConstructorParameterAnnotations.MarkerAnnotation(3)], " +
        "[]]")
    @ExpectedParameterAnnotations({
        "null",
        "@TestConstructorParameterAnnotations.MarkerAnnotation(3)",
            "null"})
    public class NestedClass3 {
        public <P> NestedClass3(@MarkerAnnotation(3) P parameter1,
                                int parameter2) {}
    }

    @ExpectedGetParameterAnnotations(
        "[[], " +
        "[@TestConstructorParameterAnnotations.MarkerAnnotation(4)], " +
        "[]]")
    @ExpectedParameterAnnotations({
        "null",
        "@TestConstructorParameterAnnotations.MarkerAnnotation(4)",
        "null"})
    public class NestedClass4 {
        public <P, Q> NestedClass4(@MarkerAnnotation(4) P parameter1,
                                   Q parameter2) {}
    }

    @ExpectedGetParameterAnnotations("[]")
    @ExpectedParameterAnnotations({"null"})
    public static class StaticNestedClass0 {
        public StaticNestedClass0() {}
    }

    @ExpectedGetParameterAnnotations(
        "[[@TestConstructorParameterAnnotations.MarkerAnnotation(1)]]")
    @ExpectedParameterAnnotations({
        "@TestConstructorParameterAnnotations.MarkerAnnotation(1)"})
    public static class StaticNestedClass1 {
        public StaticNestedClass1(@MarkerAnnotation(1) int parameter) {}
    }

    @ExpectedGetParameterAnnotations(
        "[[@TestConstructorParameterAnnotations.MarkerAnnotation(2)], " +
        "[]]")
    @ExpectedParameterAnnotations({
        "@TestConstructorParameterAnnotations.MarkerAnnotation(2)",
        "null"})
    public static class StaticNestedClass2 {
        public StaticNestedClass2(@MarkerAnnotation(2) int parameter1,
                            int parameter2) {}
    }

    @ExpectedGetParameterAnnotations(
        "[[@TestConstructorParameterAnnotations.MarkerAnnotation(3)], " +
        "[]]")
    @ExpectedParameterAnnotations({
        "@TestConstructorParameterAnnotations.MarkerAnnotation(3)",
        "null"})
    public static class StaticNestedClass3 {
        public <P> StaticNestedClass3(@MarkerAnnotation(3) P parameter1,
                                      int parameter2) {}
    }

    @ExpectedGetParameterAnnotations(
        "[[@TestConstructorParameterAnnotations.MarkerAnnotation(4)], " +
        "[]]")
    @ExpectedParameterAnnotations({
        "@TestConstructorParameterAnnotations.MarkerAnnotation(4)",
        "null"})
    public static class StaticNestedClass4 {
        public <P, Q> StaticNestedClass4(@MarkerAnnotation(4) P parameter1,
                                         Q parameter2) {}
    }

    @Target(ElementType.PARAMETER)
    @Retention(RetentionPolicy.RUNTIME)
    @interface MarkerAnnotation {
        int value();
    }

    /**
     * String form of expected value of calling
     * getParameterAnnotations on a constructor.
     */
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @interface ExpectedGetParameterAnnotations {
        String value();
    }

    /**
     * String form of expected value of calling
     * getAnnotation(MarkerAnnotation.class) on each element of the
     * result of getParameters() on a constructor.
     */
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @interface ExpectedParameterAnnotations {
        String[] value();
    }
}
