/*
 * Copyright (c) 2020, 2023, 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
 * @requires vm.gc != "Epsilon"
 * @summary Stress the string table and cleaning.
 * Test argument is the approximate number of seconds to run.
 * @library /test/lib
 * @modules java.base/jdk.internal.misc
 * @build jdk.test.whitebox.WhiteBox
 * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
 * @run main/othervm
 *    -Xbootclasspath/a:.
 *    -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
 *    runtime.stringtable.StringTableCleaningTest 30
 */

package runtime.stringtable;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import jdk.test.lib.process.OutputAnalyzer;
import jdk.test.lib.process.ProcessTools;
import jdk.test.whitebox.gc.GC;

public class StringTableCleaningTest {
    public static void main(String[] args) throws Exception {
        List<String> subargs = new ArrayList<String>();
        subargs.addAll(List.of("-Xlog:gc,gc+start,stringtable*=trace", "-Xmx1g"));
        subargs.add(Tester.class.getName());
        subargs.addAll(Arrays.asList(args));
        OutputAnalyzer output = ProcessTools.executeTestJava(subargs);
        output.shouldHaveExitValue(0);
        checkOutput(output);
    }

    private static int fail(String msg) throws Exception {
        throw new RuntimeException(msg);
    }

    // Recognizing GC start and end log lines.

    private static final String gcPrefix = "\\[info\\s*\\]\\[gc";
    private static final String gcMiddle = "\\s*\\] GC\\(\\p{Digit}+\\) ";

    private static final String gcStartPrefix = gcPrefix + ",start" + gcMiddle;
    private static final String gcEndPrefix = gcPrefix + gcMiddle;

    // Suffix for SerialGC and ParallelGC.
    private static final String spSuffix = "Pause";

    // All G1 pauses except Cleanup do weak reference clearing.
    private static final String g1Suffix = "Pause(?! Cleanup)";

    // For ZGC only major collections clean the string table. ZGC prints the
    // start message without using the start tag, hence the special prefix.
    private static final String zStartPrefix = gcPrefix + gcMiddle;
    private static final String zStartSuffix = "Major Collection \\(.*\\)$";
    private static final String zEndSuffix = "Major Collection \\(.*\\) .*->.*$";

    // Suffix for ZGC (non generational).
    private static final String xStartSuffix = "Garbage Collection (.*)$";
    private static final String xEndSuffix = "Garbage Collection (.*) .*->.*$";

    // Suffix for Shenandoah.
    private static final String shenSuffix = "Concurrent weak roots";

    private static String getGcStartString() {
        if (GC.Serial.isSelected() || GC.Parallel.isSelected()) {
            return gcStartPrefix + spSuffix;
        } else if (GC.G1.isSelected()) {
            return gcStartPrefix + g1Suffix;
        } else if (GC.Z.isSelected()) {
            return "(" + zStartPrefix + zStartSuffix + ")|(" + gcStartPrefix + xStartSuffix + ")";
        } else if (GC.Shenandoah.isSelected()) {
            return gcStartPrefix + shenSuffix;
        } else {
            return "unsupported GC";
        }
    }

    private static String getGcEndString() {
        if (GC.Serial.isSelected() || GC.Parallel.isSelected()) {
            return gcEndPrefix + spSuffix;
        } else if (GC.G1.isSelected()) {
            return gcEndPrefix + g1Suffix;
        } else if (GC.Z.isSelected()) {
            return gcEndPrefix + "(" + zEndSuffix + ")|(" + xEndSuffix + ")";
        } else if (GC.Shenandoah.isSelected()) {
            return gcEndPrefix + shenSuffix;
        } else {
            return "unsupported GC";
        }
    }

    private static Pattern getGcStartPattern() {
        return Pattern.compile(getGcStartString());
    }

    private static Pattern getGcEndPattern() {
        return Pattern.compile(getGcEndString());
    }

    private static final Pattern pGcStart = getGcStartPattern();
    private static final Pattern pGcEnd = getGcEndPattern();

    // Recognizing StringTable GC callback log lines.

    private static final Pattern pCallback =
        Pattern.compile("\\[trace\\s*\\]\\[stringtable\\s*\\] Uncleaned items:");

    private static boolean matchesPattern(String line, Pattern regex) {
        return regex.matcher(line).find();
    }

    private static boolean matchesStart(String line) {
        return matchesPattern(line, pGcStart);
    }

    private static boolean matchesEnd(String line) {
        return matchesPattern(line, pGcEnd);
    }

    private static boolean matchesCallback(String line) {
        return matchesPattern(line, pCallback);
    }

    // Search the lines for the first GC start log line in lines, starting
    // from fromIndex.  Returns the index of that line, or -1 if no GC start
    // line found.  Throws if a callback or GC end line is found first.
    private static int findStart(List<String> lines, int fromIndex)
        throws Exception
    {
        for (int i = fromIndex; i < lines.size(); ++i) {
            String line = lines.get(i);
            if (matchesStart(line)) {
                return i;
            } else if (matchesEnd(line)) {
                fail("End without Start: " + i);
            } else if (matchesCallback(line)) {
                fail("Callback without Start: " + i);
            }
        }
        return -1;
    }

    // Search the lines for the first callback log line in lines, starting
    // after gcStart.  Returns the index of that line, or -1 if no callback
    // line is found (concurrent GC could start but not complete).  Throws
    // if a GC start or GC end log line is found first.
    private static int findCallback(List<String> lines, int gcStart)
        throws Exception
    {
        for (int i = gcStart + 1; i < lines.size(); ++i) {
            String line = lines.get(i);
            if (matchesCallback(line)) {
                return i;
            } else if (matchesEnd(line)) {
                fail("Missing Callback in [" + gcStart + ", " + i + "]");
            } else if (matchesStart(line)) {
                fail("Two Starts: " + gcStart + ", " + i);
            }
        }
        return -1;
    }

    // Search the lines for the first GC end log line in lines, starting
    // after callback.  Returns the index of that line, or -1 if no GC end
    // line is found (concurrent GC could start but not complete).  Throws
    // if a GC start or a callback log line is found first.
    private static int findEnd(List<String> lines, int gcStart, int callback)
        throws Exception
    {
        for (int i = callback + 1; i < lines.size(); ++i) {
            String line = lines.get(i);
            if (matchesEnd(line)) {
                return i;
            } else if (matchesStart(line)) {
                fail("Missing End for Start: " + gcStart + " at " + i);
            } else if (matchesCallback(line)) {
                fail("Multiple Callbacks for Start: " + gcStart + " at " + i);
            }
        }
        return -1;
    }

    private static int check(List<String> lines, int fromIndex) throws Exception {
        int gcStart = findStart(lines, fromIndex);
        if (gcStart < 0) return -1;
        int callback = findCallback(lines, gcStart);
        if (callback < 0) return -1;
        int gcEnd = findEnd(lines, gcStart, callback);
        if (gcEnd < 0) return -1;
        return gcEnd + 1;
    }

    private static void checkOutput(OutputAnalyzer output) throws Exception {
        List<String> lines = output.asLines();
        int count = -1;
        int i = 0;
        try {
            for ( ; i >= 0; i = check(lines, i)) { ++count; }
        } finally {
            if (i < 0) {
                System.out.println("Output check passed with " + count + " GCs");
            } else {
                System.out.println("--- Output check failed: " + count + " -----");
                System.out.println(output.getOutput());
            }
        }
    }

    static class Tester {
        private static volatile boolean stopRequested = false;

        private static final TimeUnit durationUnits = TimeUnit.SECONDS;

        public static void main(String[] args) throws Exception {
            long duration = Long.parseLong(args[0]);
            runTest(duration);
        }

        public static void runTest(long duration) throws Exception {
            ScheduledExecutorService scheduler =
                Executors.newScheduledThreadPool(1);
            try {
                ScheduledFuture<?> stopper =
                    scheduler.schedule(() -> stopRequested = true,
                                       duration,
                                       durationUnits);
                try {
                    stringMaker(10000000, 100000, 50000);
                } finally {
                    stopper.cancel(false);
                }
            } finally {
                scheduler.shutdownNow();
            }
        }

        private static void stringMaker(int maxSize, int growStep, int shrinkStep)
            throws Exception
        {
            long stringNum = 0;
            while (true) {
                LinkedList<String> list = new LinkedList<String>();
                for (int i = 0; i < maxSize; ++i, ++stringNum) {
                    if (stopRequested) {
                        return;
                    }
                    if ((i != 0) && ((i % growStep) == 0)) {
                        list.subList(0, shrinkStep).clear();
                    }
                    list.push(Long.toString(stringNum).intern());
                }
                // For generational collectors, try to move current list
                // contents to old-gen before dropping the list.
                System.gc();
            }
        }
    }
}
