/*
 * Copyright (c) 2022, 2025, 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 8266670
 * @summary Test expected value of STRICT AccessFlag
 * @compile -source 16 -target 16 StrictAccessFlagTest.java
 * @run main StrictAccessFlagTest
 */

// Note: cannot use --release 16 because the accessFlags() method is
// not found in release 16; therefore -source and -target are used
// instead.

import java.lang.annotation.*;
import java.lang.reflect.*;
import java.util.Collections;
import java.util.EnumSet;
import java.util.Set;

import static java.lang.reflect.AccessFlag.*;

/*
 * Test expected value of ACC_STRICT access flag.
 */
// Declaring the class strictfp implicitly sets ACC_STRICT on all its
// methods and constructors.
public strictfp class StrictAccessFlagTest {
    @ExpectedFlags({PUBLIC, STATIC, VARARGS, STRICT})
    public static void main(String... args) {
        for (var ctor :
                 StrictAccessFlagTest.class.getDeclaredConstructors()) {
            checkExecutable(ctor);
        }

        for (var method :
                 StrictAccessFlagTest.class.getDeclaredMethods()) {
            checkExecutable(method);
        }
    }

    private static void checkExecutable(Executable method) {
        ExpectedFlags expected =
            method.getAnnotation(ExpectedFlags.class);
        if (expected != null) {
            Set<AccessFlag> base = EnumSet.noneOf(AccessFlag.class);
            Collections.addAll(base, expected.value());
            Set<AccessFlag> actual = method.accessFlags();
            if (!base.equals(actual)) {
                throw new RuntimeException("On " + method +
                        " expected " + base +
                        " got " + actual);
            }
        }
    }

    // Constructor
    @ExpectedFlags({PUBLIC, STRICT})
    public StrictAccessFlagTest() {}

    @Retention(RetentionPolicy.RUNTIME)
    private @interface ExpectedFlags {
        AccessFlag[] value();
    }
}
