/*
 * Copyright (c) 2024, 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 8331670 8338383
 * @summary Basic test for --sun-misc-unsafe-memory-access=<value>
 * @library /test/lib
 * @compile TryUnsafeMemoryAccess.java
 * @run junit UnsafeMemoryAccessWarnings
 */

import java.util.stream.Stream;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import static org.junit.jupiter.api.Assertions.*;

import jdk.test.lib.process.ProcessTools;
import jdk.test.lib.process.OutputAnalyzer;

class UnsafeMemoryAccessWarnings {

    /**
     * Test default is "warn"
     */
    @ParameterizedTest
    @ValueSource(strings = {
            "allocateMemory+freeMemory",
            "objectFieldOffset+putLong+getLong"
    })
    void testDefault(String input) throws Exception {
        testOneWarning(input);
    }

    /**
     * Test --sun-misc-unsafe-memory-access=allow
     */
    @Test
    void testAllow() throws Exception {
        test("allocateMemory+freeMemory+objectFieldOffset+putLong+getLong+invokeCleaner",
                "--sun-misc-unsafe-memory-access=allow")
            .shouldHaveExitValue(0)
            .shouldNotContain("WARNING: A terminally deprecated method in sun.misc.Unsafe has been called")
            .shouldNotContain("WARNING: sun.misc.Unsafe::allocateMemory")
            .shouldNotContain("WARNING: sun.misc.Unsafe::freeMemory")
            .shouldNotContain("WARNING: sun.misc.Unsafe::objectFieldOffset")
            .shouldNotContain("WARNING: sun.misc.Unsafe::putLong")
            .shouldNotContain("WARNING: sun.misc.Unsafe::getLong")
            .shouldNotContain("WARNING: sun.misc.Unsafe::invokeCleaner");
    }

    /**
     * Test --sun-misc-unsafe-memory-access=warn
     */
    @ParameterizedTest
    @ValueSource(strings = {
            "allocateMemory+freeMemory",
            "objectFieldOffset+putLong+getLong"
    })
    void testWarn(String input) throws Exception {
        testOneWarning(input, "--sun-misc-unsafe-memory-access=warn");
    }

    /**
     * Test that a warning is printed by the first memory access method only.
     * @param input comma separated list of Unsafe memory access methods to execute
     * @param vmopts VM options
     */
    private void testOneWarning(String input, String... vmopts) throws Exception {
        var output = test(input, vmopts).shouldHaveExitValue(0);

        // should be warning printed for the first memory access method
        String[] methodNames = input.split("\\+");
        String firstMethodName = methodNames[0];
        output.shouldContain("WARNING: A terminally deprecated method in sun.misc.Unsafe has been called")
            .shouldContain("WARNING: sun.misc.Unsafe::" + firstMethodName + " has been called by")
            .shouldContain("WARNING: Please consider reporting this to the maintainers of")
            .shouldContain("WARNING: sun.misc.Unsafe::" + firstMethodName + " will be removed in a future release");

        // should be no warning for the second/subsequent memory access methods
        int index = 1;
        while (index < methodNames.length) {
            String methodName = methodNames[index++];
            assertNotEquals(firstMethodName, methodName);
            output.shouldNotContain("WARNING: sun.misc.Unsafe::" + methodName);
        }
    }

    /**
     * Test --sun-misc-unsafe-memory-access=debug
     */
    @Test
    void testDebug() throws Exception {
        test("allocateMemory+freeMemory+objectFieldOffset+putLong+getLong+invokeCleaner",
                "--sun-misc-unsafe-memory-access=debug")
            .shouldHaveExitValue(0)
            .shouldContain("WARNING: sun.misc.Unsafe::allocateMemory called")
            .shouldContain("WARNING: sun.misc.Unsafe::freeMemory called")
            .shouldContain("WARNING: sun.misc.Unsafe::objectFieldOffset called")
            .shouldContain("WARNING: sun.misc.Unsafe::putLong called")
            .shouldContain("WARNING: sun.misc.Unsafe::getLong called")
            .shouldContain("WARNING: sun.misc.Unsafe::invokeCleaner called");
    }

    /**
     * Test --sun-misc-unsafe-memory-access=deny
     */
    @Test
    void testDeny() throws Exception {
        test("allocateMemory+objectFieldOffset+invokeCleaner", "--sun-misc-unsafe-memory-access=deny")
            .shouldHaveExitValue(0)
            .shouldContain("java.lang.UnsupportedOperationException: allocateMemory")
            .shouldContain("java.lang.UnsupportedOperationException: objectFieldOffset")
            .shouldContain("java.lang.UnsupportedOperationException: invokeCleaner");
    }

    /**
     * Test invoking Unsafe methods with core reflection.
     */
    @Test
    void testInvokeReflectively() throws Exception {
        test("reflectivelyAllocateMemory+reflectivelyFreeMemory", "--sun-misc-unsafe-memory-access=allow")
            .shouldHaveExitValue(0)
            .shouldNotContain("WARNING: A terminally deprecated method in sun.misc.Unsafe has been called")
            .shouldNotContain("WARNING: sun.misc.Unsafe::allocateMemory")
            .shouldNotContain("WARNING: sun.misc.Unsafe::freeMemory");

        test("reflectivelyAllocateMemory+reflectivelyFreeMemory", "--sun-misc-unsafe-memory-access=warn")
            .shouldHaveExitValue(0)
            .shouldContain("WARNING: A terminally deprecated method in sun.misc.Unsafe has been called")
            .shouldContain("WARNING: sun.misc.Unsafe::allocateMemory has been called by")
            .shouldContain("WARNING: Please consider reporting this to the maintainers of")
            .shouldContain("WARNING: sun.misc.Unsafe::allocateMemory will be removed in a future release")
            .shouldNotContain("WARNING: sun.misc.Unsafe::freeMemory");

        test("reflectivelyAllocateMemory+reflectivelyFreeMemory", "--sun-misc-unsafe-memory-access=debug")
            .shouldHaveExitValue(0)
            .shouldContain("WARNING: sun.misc.Unsafe::allocateMemory called")
            .shouldContain("WARNING: sun.misc.Unsafe::freeMemory called");

        test("reflectivelyAllocateMemory", "--sun-misc-unsafe-memory-access=deny")
            .shouldHaveExitValue(0)
            .shouldContain("java.lang.UnsupportedOperationException: allocateMemory");
    }

    /**
     * If --sun-misc-unsafe-memory-access specified more than once then last one wins.
     */
    @Test
    void testLastOneWins() throws Exception {
        test("allocateMemory+objectFieldOffset+invokeCleaner",
                "--sun-misc-unsafe-memory-access=allow",
                "--sun-misc-unsafe-memory-access=deny")
            .shouldHaveExitValue(0)
            .shouldContain("java.lang.UnsupportedOperationException: allocateMemory")
            .shouldContain("java.lang.UnsupportedOperationException: objectFieldOffset")
            .shouldContain("java.lang.UnsupportedOperationException: invokeCleaner");
    }

    /**
     * Test --sun-misc-unsafe-memory-access with invalid values.
     */
    @ParameterizedTest
    @ValueSource(strings = { "", "bad" })
    void testInvalidValues(String value) throws Exception {
        test("allocateMemory", "--sun-misc-unsafe-memory-access=" + value)
            .shouldNotHaveExitValue(0)
            .shouldContain("Value specified to --sun-misc-unsafe-memory-access not recognized: '" + value);
    }

    /**
     * Test System.setProperty("sun.misc.unsafe.memory.access", "allow")
     * The saved value from startup should be used, not the system property set at run-time.
     */
    @Test
    void testSetPropertyToAllow() throws Exception {
        test("setSystemPropertyToAllow+objectFieldOffset", "--sun-misc-unsafe-memory-access=deny")
            .shouldHaveExitValue(0)
            .shouldContain("java.lang.UnsupportedOperationException: objectFieldOffset");
    }

    /**
     * Launch TryUnsafeMemoryAccess with the given arguments and VM options.
     */
    private OutputAnalyzer test(String action, String... vmopts) throws Exception {
        Stream<String> s1 = Stream.of(vmopts);
        Stream<String> s2 = Stream.of("TryUnsafeMemoryAccess", action);
        String[] opts = Stream.concat(s1, s2).toArray(String[]::new);
        var outputAnalyzer = ProcessTools
                .executeTestJava(opts)
                .outputTo(System.err)
                .errorTo(System.err);
        return outputAnalyzer;
    }
}
