/*
 * Copyright (c) 2014, 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.
 */

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.UserPrincipal;
import java.time.Duration;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.Random;
import java.util.concurrent.TimeUnit;

import org.testng.Assert;
import org.testng.TestNG;
import org.testng.annotations.Test;

import jdk.test.lib.Platform;
import jdk.test.lib.Utils;

/*
 * @test
 * @bug 8077350 8081566 8081567 8098852 8136597
 * @requires os.arch != "riscv64" | !(vm.cpu.features ~= ".*qemu.*")
 * @library /test/lib
 * @modules java.base/jdk.internal.misc
 *          jdk.management
 * @build jdk.test.lib.Utils
 *        jdk.test.lib.Asserts
 *        jdk.test.lib.JDKToolFinder
 *        jdk.test.lib.JDKToolLauncher
 *        jdk.test.lib.Platform
 *        jdk.test.lib.process.*
 * @run testng InfoTest
 * @summary Functions of ProcessHandle.Info
 * @author Roger Riggs
 */

public class InfoTest {

    static String whoami;

    static {
        try {
            // Create a file and take the username from the file
            Path p = Paths.get("OwnerName.tmp");
            Files.createFile(p);
            UserPrincipal owner = Files.getOwner(p);
            whoami = owner.getName();
            Files.delete(p);
        } catch (IOException ex) {
            ex.printStackTrace();
            throw new UncheckedIOException("tmp file", ex);
        }
    }

    // Main can be used to run the tests from the command line with only testng.jar.
    public static void main(String[] args) {
        Class<?>[] testclass = {InfoTest.class};
        TestNG testng = new TestNG();
        testng.setTestClasses(testclass);
        testng.run();
    }

    /**
     * Test that cputime used shows up in ProcessHandle.info
     */
    @Test
    public static void test1() {
        System.out.println("Note: when run in samevm mode the cputime of the " +
                "test runner is included.");
        ProcessHandle self = ProcessHandle.current();

        Duration someCPU = Duration.ofMillis(200L);
        Instant end = Instant.now().plus(someCPU);
        while (Instant.now().isBefore(end)) {
            // waste the cpu
        }
        ProcessHandle.Info info = self.info();
        System.out.printf(" info: %s%n", info);
        Optional<Duration> totalCpu = info.totalCpuDuration();
        if (totalCpu.isPresent() && (totalCpu.get().compareTo(someCPU) < 0)) {
            Assert.fail("reported cputime less than expected: " + someCPU + ", " +
                    "actual: " + info.totalCpuDuration());
        }
    }

    /**
     * Spawn a child with arguments and check they are visible via the ProcessHandle.
     */
    @Test
    public static void test2() {
        try {
            long cpuLoopTime = 100;             // 100 ms
            String[] extraArgs = {"pid", "parent", "stdin"};
            JavaChild p1 = JavaChild.spawnJavaChild((Object[])extraArgs);
            Instant afterStart = null;

            try (BufferedReader lines = p1.outputReader()) {
                // Read the args line to know the subprocess has started
                lines.readLine();
                afterStart = Instant.now();

                Duration lastCpu = Duration.ofMillis(0L);
                for (int j = 0; j < 10; j++) {

                    p1.sendAction("cpuloop", cpuLoopTime);
                    p1.sendAction("cputime", "");

                    // Read cputime from child
                    Duration childCpuTime = null;
                    // Read lines from the child until the result from cputime is returned
                    for (String s; (s = lines.readLine()) != null;) {
                        String[] split = s.trim().split(" ");
                        if (split.length == 3 && split[1].equals("cputime")) {
                            long nanos = Long.valueOf(split[2]);
                            childCpuTime = Duration.ofNanos(nanos);
                            break;      // found the result we're looking for
                        }
                    }

                    if (Platform.isAix()) {
                        // Unfortunately, on AIX the usr/sys times reported through
                        // /proc/<pid>/psinfo which are used by ProcessHandle.Info
                        // are running slow compared to the corresponding times reported
                        // by the times()/getrusage() system calls which are used by
                        // OperatingSystemMXBean.getProcessCpuTime() and returned by
                        // the JavaChild for the "cputime" command.
                        // This is because /proc/<pid>/status is only updated once a second.
                        // So we better wait a little bit to get plausible values here.
                        Thread.sleep(1000);
                    }
                    ProcessHandle.Info info = p1.info();
                    System.out.printf(" info: %s%n", info);

                    assertUser(info);

                    Optional<String> command = info.command();
                    if (command.isPresent()) {
                        String javaExe = System.getProperty("test.jdk") +
                                File.separator + "bin" + File.separator + "java";
                        String expected = Platform.isWindows() ? javaExe + ".exe" : javaExe;
                        Path expectedPath = Paths.get(expected);
                        Path actualPath = Paths.get(command.get());
                        Assert.assertTrue(Files.isSameFile(expectedPath, actualPath),
                                "Command: expected: " + javaExe + ", actual: " + command.get());
                    }

                    if (info.arguments().isPresent()) {
                        String[] args = info.arguments().get();

                        int offset = args.length - extraArgs.length;
                        for (int i = 0; i < extraArgs.length; i++) {
                            Assert.assertEquals(args[offset + i], extraArgs[i],
                                                "Actual argument mismatch, index: " + i);
                        }

                        // Now check that the first argument is not the same as the executed command
                        if (args.length > 0) {
                            Assert.assertNotEquals(args[0], command,
                                    "First argument should not be the executable: args[0]: "
                                            + args[0] + ", command: " + command);
                        }
                    }

                    if (command.isPresent() && info.arguments().isPresent()) {
                        // If both, 'command' and 'arguments' are present,
                        // 'commandLine' is just the concatenation of the two.
                        Assert.assertTrue(info.commandLine().isPresent(),
                                          "commandLine() must be available");

                        String javaExe = System.getProperty("test.jdk") +
                                File.separator + "bin" + File.separator + "java";
                        String expected = Platform.isWindows() ? javaExe + ".exe" : javaExe;
                        Path expectedPath = Paths.get(expected);
                        String commandLine = info.commandLine().get();
                        String commandLineCmd = commandLine.split(" ")[0];
                        Path commandLineCmdPath = Paths.get(commandLineCmd);
                        Assert.assertTrue(Files.isSameFile(commandLineCmdPath, expectedPath),
                                          "commandLine() should start with: " + expectedPath +
                                          " but starts with " + commandLineCmdPath);

                        Assert.assertTrue(commandLine.contains(command.get()),
                                "commandLine() must contain the command: " + command.get());
                        List<String> allArgs = p1.getArgs();
                        for (int i = 1; i < allArgs.size(); i++) {
                            Assert.assertTrue(commandLine.contains(allArgs.get(i)),
                                              "commandLine() must contain argument: " + allArgs.get(i));
                        }
                    } else if (info.commandLine().isPresent() &&
                            command.isPresent() &&
                            command.get().length() < info.commandLine().get().length()) {
                        // If we only have the commandLine() we can only do some basic checks...
                        String commandLine = info.commandLine().get();
                        String javaExe = "java" + (Platform.isWindows() ? ".exe" : "");
                        int pos = commandLine.indexOf(javaExe);
                        Assert.assertTrue(pos > 0, "commandLine() should at least contain 'java'");

                        pos += javaExe.length() + 1; // +1 for the space after the command
                        List<String> allArgs = p1.getArgs();
                        // First argument is the command - skip it here as we've already checked that.
                        for (int i = 1; (i < allArgs.size()) &&
                                        (pos + allArgs.get(i).length() < commandLine.length()); i++) {
                            Assert.assertTrue(commandLine.contains(allArgs.get(i)),
                                              "commandLine() must contain argument: " + allArgs.get(i));
                            pos += allArgs.get(i).length() + 1;
                        }
                    }

                    if (info.totalCpuDuration().isPresent()) {
                        Duration totalCPU = info.totalCpuDuration().get();
                        Duration epsilon = Duration.ofMillis(200L);
                        if (childCpuTime != null) {
                            System.out.printf(" info.totalCPU: %s, childCpuTime: %s, diff: %s%n",
                                    totalCPU.toNanos(), childCpuTime.toNanos(),
                                    childCpuTime.toNanos() - totalCPU.toNanos());
                            Assert.assertTrue(checkEpsilon(childCpuTime, totalCPU, epsilon),
                                    childCpuTime + " should be within " +
                                            epsilon + " of " + totalCPU);
                        }
                        Assert.assertTrue(totalCPU.toNanos() > 0L,
                                "total cpu time expected > 0ms, actual: " + totalCPU);
                        long t = Utils.adjustTimeout(10L);  // Adjusted timeout seconds
                        Assert.assertTrue(totalCPU.toNanos() < lastCpu.toNanos() + t * 1_000_000_000L,
                                "total cpu time expected < " + t
                                        + " seconds more than previous iteration, actual: "
                                        + (totalCPU.toNanos() - lastCpu.toNanos()));
                        lastCpu = totalCPU;
                    }

                    if (info.startInstant().isPresent()) {
                        Instant startTime = info.startInstant().get();
                        Assert.assertTrue(startTime.isBefore(afterStart),
                                "startTime after process spawn completed"
                                        + startTime + " + > " + afterStart);
                    }
                }
            }
            p1.sendAction("exit");
            Assert.assertTrue(p1.waitFor(Utils.adjustTimeout(30L), TimeUnit.SECONDS),
                    "timeout waiting for process to terminate");
        } catch (IOException | InterruptedException ie) {
            ie.printStackTrace(System.out);
            Assert.fail("unexpected exception", ie);
        } finally {
            // Destroy any children that still exist
            ProcessUtil.destroyProcessTree(ProcessHandle.current());
        }
    }

    /**
     * Spawn a child with arguments and check they are visible via the ProcessHandle.
     */
    @Test
    public static void test3() {
        try {
            for (long sleepTime : Arrays.asList(Utils.adjustTimeout(30), Utils.adjustTimeout(32))) {
                Process p = spawn("sleep", String.valueOf(sleepTime));

                ProcessHandle.Info info = p.info();
                System.out.printf(" info: %s%n", info);

                assertUser(info);

                if (info.command().isPresent()) {
                    String command = info.command().get();
                    String expected = "sleep";
                    if (Platform.isWindows()) {
                        expected = "sleep.exe";
                    } else if (Files.isSymbolicLink(Paths.get("/bin/sleep"))) {
                        // Busybox sleep is a symbolic link to /bin/busybox.
                        // Rust coreutils sleep is a symbolic link to coreutils
                        // The busbox/coreutils executables are seen as ProcessHandle.Info command.
                        Path executable = Files.readSymbolicLink(Paths.get("/bin/sleep"));
                        expected = executable.getFileName().toString();
                    }
                    Assert.assertTrue(command.endsWith(expected), "Command: expected: \'" +
                            expected + "\', actual: " + command);

                    // Verify the command exists and is executable
                    File exe = new File(command);
                    Assert.assertTrue(exe.exists(), "command must exist: " + exe);
                    Assert.assertTrue(exe.canExecute(), "command must be executable: " + exe);
                }
                if (info.arguments().isPresent()) {
                    String[] args = info.arguments().get();
                    if (args.length > 0) {
                        Assert.assertEquals(args[0], String.valueOf(sleepTime));
                    }
                }
                p.destroy();
                Assert.assertTrue(p.waitFor(Utils.adjustTimeout(30), TimeUnit.SECONDS),
                        "timeout waiting for process to terminate");
            }
        } catch (IOException | InterruptedException ex) {
            ex.printStackTrace(System.out);
        } finally {
            // Destroy any children that still exist
            ProcessUtil.destroyProcessTree(ProcessHandle.current());
        }
    }

    /**
     * Cross check the cputime reported from java.management with that for the current process.
     */
    @Test
    public static void test4() {
        Duration myCputime1 = ProcessUtil.MXBeanCpuTime();

        if (Platform.isAix()) {
            // Unfortunately, on AIX the usr/sys times reported through
            // /proc/<pid>/psinfo which are used by ProcessHandle.Info
            // are running slow compared to the corresponding times reported
            // by the times()/getrusage() system calls which are used by
            // OperatingSystemMXBean.getProcessCpuTime() and returned by
            // the JavaChild for the "cputime" command.
            // So we better wait a little bit to get plausible values here.
            try {
                Thread.sleep(1000);
            } catch (InterruptedException ex) {}
        }
        Optional<Duration> dur1 = ProcessHandle.current().info().totalCpuDuration();

        Duration myCputime2 = ProcessUtil.MXBeanCpuTime();

        if (Platform.isAix()) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException ex) {}
        }
        Optional<Duration> dur2 = ProcessHandle.current().info().totalCpuDuration();

        if (dur1.isPresent() && dur2.isPresent()) {
            Duration total1 = dur1.get();
            Duration total2 = dur2.get();
            System.out.printf(" total1 vs. mbean: %s, getProcessCpuTime: %s, diff: %s%n",
                    Objects.toString(total1), myCputime1, myCputime1.minus(total1));
            System.out.printf(" total2 vs. mbean: %s, getProcessCpuTime: %s, diff: %s%n",
                    Objects.toString(total2), myCputime2, myCputime2.minus(total2));

            Duration epsilon = Duration.ofMillis(200L);      // Epsilon is 200ms.
            Assert.assertTrue(checkEpsilon(myCputime1, myCputime2, epsilon),
                    myCputime1.toNanos() + " should be within " + epsilon
                            + " of " + myCputime2.toNanos());
            Assert.assertTrue(checkEpsilon(total1, total2, epsilon),
                    total1.toNanos() + " should be within " + epsilon
                            + " of " + total2.toNanos());
            Assert.assertTrue(checkEpsilon(myCputime1, total1, epsilon),
                    myCputime1.toNanos() + " should be within " + epsilon
                            + " of " + total1.toNanos());
            Assert.assertTrue(checkEpsilon(total1, myCputime2, epsilon),
                    total1.toNanos() + " should be within " + epsilon
                            + " of " + myCputime2.toNanos());
            Assert.assertTrue(checkEpsilon(myCputime2, total2, epsilon),
                    myCputime2.toNanos() + " should be within " + epsilon
                            + " of " + total2.toNanos());
        }
    }

    @Test
    public static void test5() {
        ProcessHandle self = ProcessHandle.current();
        Random r = new Random();
        for (int i = 0; i < 30; i++) {
            Instant end = Instant.now().plusMillis(500L);
            while (end.isBefore(Instant.now())) {
                // burn the cpu time checking the time
                r.nextLong();
            }
            if (self.info().totalCpuDuration().isPresent()) {
                Duration totalCpu = self.info().totalCpuDuration().get();
                long infoTotalCputime = totalCpu.toNanos();
                long beanCputime = ProcessUtil.MXBeanCpuTime().toNanos();
                System.out.printf(" infoTotal: %12d, beanCpu: %12d, diff: %12d%n",
                        infoTotalCputime, beanCputime, beanCputime - infoTotalCputime);
            } else {
                break;  // nothing to compare; continue
            }
        }
    }

    /**
     * Check two Durations, the second should be greater than the first or
     * within the supplied Epsilon.
     * @param d1 a Duration - presumed to be shorter
     * @param d2 a 2nd Duration - presumed to be greater (or within Epsilon)
     * @param epsilon Epsilon the amount of overlap allowed
     * @return true if d2 is greater than d1 or within epsilon, false otherwise
     */
    static boolean checkEpsilon(Duration d1, Duration d2, Duration epsilon) {
        if (d1.toNanos() <= d2.toNanos()) {
            return true;
        }
        Duration diff = d1.minus(d2).abs();
        return diff.compareTo(epsilon) <= 0;
    }

    /**
     * Spawn a native process with the provided arguments.
     * @param command the executable of native process
     * @param args to start a new process
     * @return the Process that was started
     * @throws IOException thrown by ProcessBuilder.start
     */
    static Process spawn(String command, String... args) throws IOException {
        ProcessBuilder pb = new ProcessBuilder();
        pb.inheritIO();
        List<String> list = new ArrayList<>();
        list.add(command);
        for (String arg : args)
            list.add(arg);
        pb.command(list);
        return pb.start();
    }

    /**
     * Asserts the expected process user.
     *
     * The Expected user is determined by creating a file and reading its owner, see static block above.
     *
     * On Windows, when run privileged as member of the Administrators group, this does not always
     * work because new files can be owned by BUILTIN\Administrators instead, depending on system
     * settings. In that case we resort to comparing System property user.name, which does not contain
     * the domain name, though.
     *
     * @param info ProcessHanlde info object
     */
    static void assertUser(ProcessHandle.Info info) {
        if (!info.user().isPresent()) {
            return;
        }
        String user = info.user().get();
        Assert.assertNotNull(user, "User name");
        if (Platform.isWindows() && "BUILTIN\\Administrators".equals(whoami)) {
            int bsi = user.lastIndexOf("\\");
            Assert.assertEquals(bsi == -1 ? user : user.substring(bsi + 1),
                    System.getProperty("user.name"), "User name");
        } else {
            Assert.assertEquals(user, whoami, "User name");
        }
    }
}
