/*
 * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
 * Copyright (c) 2018, 2020 SAP SE. 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
 * @summary Validate and test -?, -h and --help flags. All tools in the jdk
 *          should take the same flags to display the help message. These
 *          flags should be documented in the printed help message. The
 *          tool should quit without error code after displaying the
 *          help message (if there  is no other problem with the command
 *          line).
 *          Also check that tools that used to accept -help still do
 *          so. Test that tools that never accepted -help don't do so
 *          in future. I.e., check that the tool returns with the same
 *          return code as called with an invalid flag, and does not
 *          print anything containing '-help' in that case.
 * @compile HelpFlagsTest.java
 * @run main HelpFlagsTest
 */

import java.io.File;

public class HelpFlagsTest extends TestHelper {

    // Tools that should not be tested because a usage message is pointless.
    static final String[] TOOLS_NOT_TO_TEST = {
        "jaccessinspector", // gui, don't test, win only
        "jaccessinspector-32", // gui, don't test, win-32 only
        "jaccesswalker",    // gui, don't test, win only
        "jaccesswalker-32", // gui, don't test, win-32 only
        "jconsole",         // gui, don't test
        "servertool",       // none. Shell, don't test.
        "javaw",            // don't test, win only
        // These shall have a help message that resembles that of
        // MIT's tools. Thus -?, -h and --help are supported, but not
        // mentioned in the help text.
        "kinit",
        "klist",
        "ktab",
        // Oracle proprietary tools without help message.
        "javacpl",
        "jmc",
        "jweblauncher",
        "jcontrol",
        "ssvagent"
    };

    // Lists which tools support which flags.
    private static class ToolHelpSpec {
        String toolname;

        // How the flags supposed to be supported are handled.
        //
        // These flags are supported, i.e.,
        // * the tool accepts the flag
        // * the tool prints a help message if the flag is specified
        // * this help message lists the flag
        // * the tool exits with exit code '0'.
        boolean supportsQuestionMark;
        boolean supportsH;
        boolean supportsHelp;

        // One tool returns with exit code != '0'.
        int exitcodeOfHelp;

        // How legacy -help is handled.
        //
        // Tools that so far support -help should still do so, but
        // not print documentation about it. Tools that do not
        // support -help should not do so in future.
        //
        // The tools accepts legacy -help. -help should not be
        // documented in the usage message.
        boolean supportsLegacyHelp;

        // Java itself documents -help. -help prints to stderr,
        // while --help prints to stdout. Leave as is.
        boolean documentsLegacyHelp;

        // The exit code of the tool if an invalid argument is passed to it.
        // An exit code != 0 would be expected, but not all tools handle it
        // that way.
        int exitcodeOfWrongFlag;

        ToolHelpSpec(String n, int q, int h, int hp, int ex1, int l, int dl, int ex2) {
            toolname = n;
            supportsQuestionMark = ( q  == 1 ? true : false );
            supportsH            = ( h  == 1 ? true : false );
            supportsHelp         = ( hp == 1 ? true : false );
            exitcodeOfHelp       = ex1;

            supportsLegacyHelp   = (  l == 1 ? true : false );
            documentsLegacyHelp  = ( dl == 1 ? true : false );
            exitcodeOfWrongFlag  = ex2;
        }
    }

    static ToolHelpSpec[] jdkTools = {
        //               name          -?   -h --help exitcode   -help -help  exitcode
        //                                            of help          docu   of wrong
        //                                                             mented flag
        new ToolHelpSpec("jabswitch",   0,   0,   0,   0,         0,    0,     0),     // /?, prints help message anyways, win only
        new ToolHelpSpec("jar",         1,   1,   1,   0,         0,    0,     1),     // -?, -h, --help
        new ToolHelpSpec("jarsigner",   1,   1,   1,   0,         1,    0,     1),     // -?, -h, --help, -help accepted but not documented.
        new ToolHelpSpec("java",        1,   1,   1,   0,         1,    1,     1),     // -?, -h, --help -help, Documents -help
        new ToolHelpSpec("javac",       1,   0,   1,   0,         1,    1,     2),     // -?,     --help -help, Documents -help, -h is already taken for "native header output directory".
        new ToolHelpSpec("javadoc",     1,   1,   1,   0,         1,    1,     1),     // -?, -h, --help -help, Documents -help
        new ToolHelpSpec("javap",       1,   1,   1,   0,         1,    1,     2),     // -?, -h, --help -help, Documents -help
        new ToolHelpSpec("javaw",       1,   1,   1,   0,         1,    1,     1),     // -?, -h, --help -help, Documents -help, win only
        new ToolHelpSpec("jcmd",        1,   1,   1,   0,         1,    0,     1),     // -?, -h, --help, -help accepted but not documented.
        new ToolHelpSpec("jdb",         1,   1,   1,   0,         1,    1,     0),     // -?, -h, --help -help, Documents -help
        new ToolHelpSpec("jdeprscan",   1,   1,   1,   0,         0,    0,     1),     // -?, -h, --help
        new ToolHelpSpec("jdeps",       1,   1,   1,   0,         1,    0,     2),     // -?, -h, --help, -help accepted but not documented.
        new ToolHelpSpec("jfr",         1,   1,   1,   0,         0,    0,     2),     // -?, -h, --help
        new ToolHelpSpec("jhsdb",       0,   0,   0,   0,         0,    0,     0),     // none, prints help message anyways.
        new ToolHelpSpec("jimage",      1,   1,   1,   0,         0,    0,     2),     // -?, -h, --help
        new ToolHelpSpec("jinfo",       1,   1,   1,   0,         1,    1,     1),     // -?, -h, --help -help, Documents -help
        new ToolHelpSpec("jjs",         0,   1,   1, 100,         0,    0,   100),     //     -h, --help, return code 100
        new ToolHelpSpec("jlink",       1,   1,   1,   0,         0,    0,     2),     // -?, -h, --help
        new ToolHelpSpec("jmap",        1,   1,   1,   0,         1,    0,     1),     // -?, -h, --help, -help accepted but not documented.
        new ToolHelpSpec("jmod",        1,   1,   1,   0,         1,    0,     2),     // -?, -h, --help, -help accepted but not documented.
        new ToolHelpSpec("jnativescan", 1,   1,   1,   0,         1,    0,     1),     // -?, -h, --help, -help accepted but not documented.
        new ToolHelpSpec("jps",         1,   1,   1,   0,         1,    1,     1),     // -?, -h, --help -help, Documents -help
        new ToolHelpSpec("jrunscript",  1,   1,   1,   0,         1,    1,     7),     // -?, -h, --help -help, Documents -help
        new ToolHelpSpec("jshell",      1,   1,   1,   0,         1,    0,     1),     // -?, -h, --help, -help accepted but not documented.
        new ToolHelpSpec("jstack",      1,   1,   1,   0,         1,    1,     1),     // -?, -h, --help -help, Documents -help
        new ToolHelpSpec("jstat",       1,   1,   1,   0,         1,    1,     1),     // -?, -h, --help -help, Documents -help
        new ToolHelpSpec("jstatd",      1,   1,   1,   0,         0,    0,     1),     // -?, -h, --help
        new ToolHelpSpec("keytool",     1,   1,   1,   0,         1,    0,     1),     // none, prints help message anyways.
        new ToolHelpSpec("rmiregistry", 0,   0,   0,   0,         0,    0,     1),     // none, prints help message anyways.
        new ToolHelpSpec("serialver",   0,   0,   0,   0,         0,    0,     1),     // none, prints help message anyways.
        new ToolHelpSpec("jpackage",    0,   1,   1,   0,         0,    1,     1),     //     -h, --help,
        new ToolHelpSpec("jwebserver",  1,   1,   1,   0,         0,    1,     1),     // -?, -h, --help
    };

    // Returns corresponding object from jdkTools array.
    static ToolHelpSpec getToolHelpSpec(String tool) {
        for (ToolHelpSpec x : jdkTools) {
            if (tool.toLowerCase().equals(x.toolname) ||
                tool.toLowerCase().equals(x.toolname + ".exe"))
                return x;
        }
        return null;
    }

    // Check whether 'flag' appears in 'line' as a word of itself. It must not
    // be a substring of a word, as then similar flags might be matched.
    // E.g.: --help matches in the documentation of --help-extra.
    // This works only with english locale, as some tools have translated
    // usage messages.
    static boolean findFlagInLine(String line, String flag) {
        if (line.contains(flag) &&
            !line.contains("nknown") &&                       // Some tools say 'Unknown option "<flag>"',
            !line.contains("invalid flag") &&                 // 'invalid flag: <flag>'
            !line.contains("invalid option") &&               // or 'invalid option: <flag>'. Skip that.
            !line.contains("FileNotFoundException: -help") && // Special case for idlj.
            !line.contains("-h requires an argument") &&      // Special case for javac.
            !line.contains("port argument,")) {               // Special case for rmiregistry.
            // There might be several appearances of 'flag' in
            // 'line'. (-h as substring of --help).
            int flagLen = flag.length();
            int lineLen = line.length();
            for (int i = line.indexOf(flag); i >= 0; i = line.indexOf(flag, i+1)) {
                // There should be a space before 'flag' in 'line', or it's right at the beginning.
                if (i > 0 &&
                    line.charAt(i-1) != ' ' &&
                    line.charAt(i-1) != '[' &&  // jarsigner
                    line.charAt(i-1) != '|' &&  // jstatd
                    line.charAt(i-1) != '\t') { // jjs
                    continue;
                }
                // There should be a space or comma after 'flag' in 'line', or it's just at the end.
                int posAfter = i + flagLen;
                if (posAfter < lineLen &&
                    line.charAt(posAfter) != ' ' &&
                    line.charAt(posAfter) != ',' &&
                    line.charAt(posAfter) != '[' && // jar
                    line.charAt(posAfter) != ']' && // jarsigner
                    line.charAt(posAfter) != ')' && // jfr
                    line.charAt(posAfter) != '|' && // jstatd
                    line.charAt(posAfter) != ':' && // jps
                    line.charAt(posAfter) != '"') { // keytool
                    continue;
                }
                return true;
            }
        }
        return false;
    }

    static TestResult runToolWithFlag(File f, String flag) {
        String x = f.getAbsolutePath();
        TestResult tr = doExec(x, flag);
        System.out.println("Testing " + f.getName());
        System.out.println("#> " + x + " " + flag);
        tr.testOutput.forEach(System.out::println);
        System.out.println("#> echo $?");
        System.out.println(tr.exitValue);

        return tr;
    }

    // Checks whether tool supports flag 'flag' and documents it
    // in the help message.
    static String testTool(File f, String flag, int exitcode) {
        String result = "";
        TestResult tr = runToolWithFlag(f, flag);

        // Check that the tool accepted the flag.
        if (exitcode == 0 && !tr.isOK()) {
            System.out.println("failed");
            result = "failed: " + f.getName() + " " + flag + " has exit code " + tr.exitValue + ".\n";
        }

        // Check there is a help message listing the flag.
        boolean foundFlag = false;
        for (String y : tr.testOutput) {
            if (!foundFlag && findFlagInLine(y, flag)) { // javac
                foundFlag = true;
                System.out.println("Found documentation of '" + flag + "': '" + y.trim() +"'");
            }
        }
        if (!foundFlag) {
            result += "failed: " + f.getName() + " does not document " +
                flag + " in help message.\n";
        }

        if (!result.isEmpty())
            System.out.println(result);

        return result;
    }

    // Test the tool supports legacy option -help, but does
    // not document it.
    static String testLegacyFlag(File f, int exitcode) {
        String result = "";
        TestResult tr = runToolWithFlag(f, "-help");

        // Check that the tool accepted the flag.
        if (exitcode == 0 && !tr.isOK()) {
            System.out.println("failed");
            result = "failed: " + f.getName() + " -help has exit code " + tr.exitValue + ".\n";
        }

        // Check there is _no_ documentation of -help.
        boolean foundFlag = false;
        for (String y : tr.testOutput) {
            if (!foundFlag && findFlagInLine(y, "-help")) {  // javac
                foundFlag = true;
                System.out.println("Found documentation of '-help': '" + y.trim() +"'");
            }
        }
        if (foundFlag) {
            result += "failed: " + f.getName() + " does document -help " +
                "in help message. This legacy flag should not be documented.\n";
        }

        if (!result.isEmpty())
            System.out.println(result);

        return result;
    }

    // Test that the tool exits with the exit code expected for
    // invalid flags. In general, one would expect this to be != 0,
    // but currently a row of tools exit with 0 in this case.
    // The output should not ask to get help with flag '-help'.
    static String testInvalidFlag(File f, String flag, int exitcode, boolean documentsLegacyHelp) {
        String result = "";
        TestResult tr = runToolWithFlag(f, flag);

        // Check that the tool did exit with the expected return code.
        if (!((exitcode == tr.exitValue) ||
              // Windows reports -1 where unix reports 255.
              (tr.exitValue < 0 && exitcode == tr.exitValue + 256))) {
            System.out.println("failed");
            result = "failed: " + f.getName() + " " + flag + " should not be " +
                     "accepted. But it has exit code " + tr.exitValue + ".\n";
        }

        if (!documentsLegacyHelp) {
            // Check there is _no_ documentation of -help.
            boolean foundFlag = false;
            for (String y : tr.testOutput) {
                if (!foundFlag && findFlagInLine(y, "-help")) {  // javac
                    foundFlag = true;
                    System.out.println("Found documentation of '-help': '" + y.trim() +"'");
                }
            }
            if (foundFlag) {
                result += "failed: " + f.getName() + " does document -help " +
                    "in error message. This legacy flag should not be documented.\n";
            }
        }

        if (!result.isEmpty())
            System.out.println(result);

        return result;
    }

    public static void main(String[] args) {
        String errorMessage = "";

        // The test analyses the help messages printed. It assumes englisch
        // help messages. Thus it only works with english locale.
        if (!isEnglishLocale()) { return; }

        for (File f : new File(JAVA_BIN).listFiles(new ToolFilter(TOOLS_NOT_TO_TEST))) {
            String toolName = f.getName();

            ToolHelpSpec tool = getToolHelpSpec(toolName);
            if (tool == null) {
                errorMessage += "Tool " + toolName + " not covered by this test. " +
                    "Add specification to jdkTools array!\n";
                continue;
            }

            // Test for help flags to be supported.
            if (tool.supportsQuestionMark == true) {
                errorMessage += testTool(f, "-?", tool.exitcodeOfHelp);
            } else {
                System.out.println("Skip " + tool.toolname + ". It does not support -?.");
            }
            if (tool.supportsH == true) {
                errorMessage += testTool(f, "-h", tool.exitcodeOfHelp);
            } else {
                System.out.println("Skip " + tool.toolname + ". It does not support -h.");
            }
            if (tool.supportsHelp == true) {
                errorMessage += testTool(f, "--help", tool.exitcodeOfHelp);
            } else {
                System.out.println("Skip " + tool.toolname + ". It does not support --help.");
            }

            // Check that the return code listing in jdkTools[] is
            // correct for an invalid flag.
            errorMessage += testInvalidFlag(f, "-asdfxgr", tool.exitcodeOfWrongFlag, tool.documentsLegacyHelp);

            // Test for legacy -help flag.
            if (!tool.documentsLegacyHelp) {
                if (tool.supportsLegacyHelp == true) {
                    errorMessage += testLegacyFlag(f, tool.exitcodeOfHelp);
                } else {
                    errorMessage += testInvalidFlag(f, "-help", tool.exitcodeOfWrongFlag, false);
                }
            }
        }

        if (errorMessage.isEmpty()) {
            System.out.println("All help string tests: PASS");
        } else {
            throw new AssertionError("HelpFlagsTest failed:\n" + errorMessage);
        }
    }
}
