/*
 * 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.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * 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.
 */
package java.lang;

import java.time.Duration;
import java.time.Instant;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Stream;

/**
 * ProcessHandle identifies and provides control of native processes. Each
 * individual process can be monitored for liveness, list its children,
 * get information about the process or destroy it.
 * By comparison, {@link java.lang.Process Process} instances were started
 * by the current process and additionally provide access to the process
 * input, output, and error streams.
 * <p>
 * The native process ID is an identification number that the
 * operating system assigns to the process.
 * The range for process id values is dependent on the operating system.
 * For example, an embedded system might use a 16-bit value.
 * Status information about a process is retrieved from the native system
 * and may change asynchronously; processes may be created or terminate
 * spontaneously.
 * The time between when a process terminates and the process id
 * is reused for a new process is unpredictable.
 * Race conditions can exist between checking the status of a process and
 * acting upon it. When using ProcessHandles avoid assumptions
 * about the liveness or identity of the underlying process.
 * <p>
 * Each ProcessHandle identifies and allows control of a process in the native
 * system. ProcessHandles are returned from the factory methods {@link #current()},
 * {@link #of(long)},
 * {@link #children}, {@link #descendants}, {@link #parent()} and
 * {@link #allProcesses()}.
 * <p>
 * The {@link Process} instances created by {@link ProcessBuilder} can be queried
 * for a ProcessHandle that provides information about the Process.
 * ProcessHandle references should not be freely distributed.
 *
 * <p>
 * A {@link java.util.concurrent.CompletableFuture} available from {@link #onExit}
 * can be used to wait for process termination, and possibly trigger dependent
 * actions.
 * <p>
 * The ability to control processes may be restricted by the native system,
 * ProcessHandle provides no more access to, or control over, the native process
 * than would be allowed by a native application.
 *
 * @implSpec
 * In the case where ProcessHandles cannot be supported then the factory
 * methods must consistently throw {@link java.lang.UnsupportedOperationException}.
 * The methods of this class throw {@link java.lang.UnsupportedOperationException}
 * if the operating system does not allow access to query or kill a process.
 *
 * <p>
 * The {@code ProcessHandle} static factory methods return instances that are
 * <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a>,
 * immutable and thread-safe. Programmers should treat instances that are
 * {@linkplain #equals(Object) equal} as interchangeable and should not
 * use instances for synchronization, or unpredictable behavior may occur.
 * For example, in a future release, synchronization may fail.
 * Use the {@code equals} or {@link #compareTo(ProcessHandle) compareTo} methods
 * to compare ProcessHandles.
 *
 * @see Process
 * @since 9
 */
public interface ProcessHandle extends Comparable<ProcessHandle> {

    /**
     * Returns the native process ID of the process. The native process ID is an
     * identification number that the operating system assigns to the process.
     * The operating system may reuse the process ID after a process terminates.
     * Use {@link #equals(Object) equals} or
     * {@link #compareTo(ProcessHandle) compareTo} to compare ProcessHandles.
     *
     * @return the native process ID of the process
     * @throws UnsupportedOperationException if the implementation
     *         does not support this operation
     */
    long pid();

    /**
     * Returns an {@code Optional<ProcessHandle>} for an existing native process.
     *
     * @param pid a native process ID
     * @return an {@code Optional<ProcessHandle>} of the PID for the process;
     *         the {@code Optional} is empty if the process does not exist
     * @throws UnsupportedOperationException if the implementation
     *         does not support this operation
     */
    static Optional<ProcessHandle> of(long pid) {
        return ProcessHandleImpl.get(pid);
    }

    /**
     * Returns a ProcessHandle for the current process. The ProcessHandle cannot be
     * used to destroy the current process, use {@link System#exit System.exit} instead.
     *
     * @return a ProcessHandle for the current process
     * @throws UnsupportedOperationException if the implementation
     *         does not support this operation
     */
    static ProcessHandle current() {
        return ProcessHandleImpl.current();
    }

    /**
     * Returns an {@code Optional<ProcessHandle>} for the parent process.
     * Note that Processes in a zombie state usually don't have a parent.
     *
     * @return an {@code Optional<ProcessHandle>} of the parent process;
     *         the {@code Optional} is empty if the child process does not have a parent
     *         or if the parent is not available, possibly due to operating system limitations
     */
    Optional<ProcessHandle> parent();

    /**
     * Returns a snapshot of the current direct children of the process.
     * The {@link #parent} of a direct child process is the process.
     * Typically, a process that is {@link #isAlive not alive} has no children.
     * <p>
     * <em>Note that processes are created and terminate asynchronously.
     * There is no guarantee that a process is {@link #isAlive alive}.
     * </em>
     *
     * @return a sequential Stream of ProcessHandles for processes that are
     *         direct children of the process
     */
    Stream<ProcessHandle> children();

    /**
     * Returns a snapshot of the descendants of the process.
     * The descendants of a process are the children of the process
     * plus the descendants of those children, recursively.
     * Typically, a process that is {@link #isAlive not alive} has no children.
     * <p>
     * <em>Note that processes are created and terminate asynchronously.
     * There is no guarantee that a process is {@link #isAlive alive}.
     * </em>
     *
     * @return a sequential Stream of ProcessHandles for processes that
     *         are descendants of the process
     */
    Stream<ProcessHandle> descendants();

    /**
     * Returns a snapshot of all processes visible to the current process.
     * <p>
     * <em>Note that processes are created and terminate asynchronously. There
     * is no guarantee that a process in the stream is alive or that no other
     * processes may have been created since the inception of the snapshot.
     * </em>
     *
     * @return a Stream of ProcessHandles for all processes
     * @throws UnsupportedOperationException if the implementation
     *         does not support this operation
     */
    static Stream<ProcessHandle> allProcesses() {
        return ProcessHandleImpl.children(0);
    }

    /**
     * Returns a snapshot of information about the process.
     *
     * <p> A {@link ProcessHandle.Info} instance has accessor methods that return
     * information about the process if it is available.
     *
     * @return a snapshot of information about the process, always non-null
     */
    Info info();

    /**
     * Information snapshot about the process.
     * The attributes of a process vary by operating system and are not available
     * in all implementations.  Information about processes is limited
     * by the operating system privileges of the process making the request.
     * The return types are {@code Optional<T>} allowing explicit tests
     * and actions if the value is available.
     * @since 9
     */
    interface Info {
        /**
         * Returns the executable pathname of the process.
         *
         * @return an {@code Optional<String>} of the executable pathname
         *         of the process
         */
        Optional<String> command();

        /**
         * Returns the command line of the process.
         * <p>
         * If {@link #command command()} and  {@link #arguments arguments()} return
         * non-empty optionals, this is simply a convenience method which concatenates
         * the values of the two functions separated by spaces. Otherwise, it will return a
         * best-effort, platform dependent representation of the command line.
         *
         * @apiNote Note that the returned executable pathname and the
         *          arguments may be truncated on some platforms due to system
         *          limitations.
         *          <p>
         *          The executable pathname may contain only the
         *          name of the executable without the full path information.
         *          It is undecidable whether white space separates different
         *          arguments or is part of a single argument.
         *
         * @return an {@code Optional<String>} of the command line
         *         of the process
         */
        Optional<String> commandLine();

        /**
         * Returns an array of Strings of the arguments of the process.
         *
         * @apiNote On some platforms, native applications are free to change
         *          the arguments array after startup and this method may only
         *          show the changed values.
         *
         * @return an {@code Optional<String[]>} of the arguments of the process
         */
        Optional<String[]> arguments();

        /**
         * Returns the start time of the process.
         *
         * @return an {@code Optional<Instant>} of the start time of the process
         */
        Optional<Instant> startInstant();

        /**
         * Returns the total cputime accumulated of the process.
         *
         * @return an {@code Optional<Duration>} for the accumulated total cputime
         */
        Optional<Duration> totalCpuDuration();

        /**
         * Return the user of the process.
         *
         * @return an {@code Optional<String>} for the user of the process
         */
        Optional<String> user();
    }

    /**
     * Returns a {@code CompletableFuture<ProcessHandle>} for the termination
     * of the process.
     * The {@link java.util.concurrent.CompletableFuture} provides the ability
     * to trigger dependent functions or actions that may be run synchronously
     * or asynchronously upon process termination.
     * When the process has terminated the CompletableFuture is
     * {@link java.util.concurrent.CompletableFuture#complete completed} regardless
     * of the exit status of the process.
     * The {@code onExit} method can be called multiple times to invoke
     * independent actions when the process exits.
     * <p>
     * Calling {@code onExit().get()} waits for the process to terminate and returns
     * the ProcessHandle. The future can be used to check if the process is
     * {@link java.util.concurrent.CompletableFuture#isDone done} or to
     * {@link java.util.concurrent.Future#get() wait} for it to terminate.
     * {@link java.util.concurrent.Future#cancel(boolean) Cancelling}
     * the {@linkplain CompletableFuture CompletableFuture} does not affect the Process.
     * @apiNote
     * The process may be observed to have terminated with {@link #isAlive}
     * before the {@code CompletableFuture} is completed and dependent actions are invoked.
     * @return a new {@code CompletableFuture<ProcessHandle>} for the ProcessHandle
     * @throws IllegalStateException if the process is the current process
     */
    CompletableFuture<ProcessHandle> onExit();

    /**
     * Returns {@code true} if the implementation of {@link #destroy}
     * normally terminates the process.
     * Returns {@code false} if the implementation of {@code destroy}
     * forcibly and immediately terminates the process.
     *
     * @return {@code true} if the implementation of {@link #destroy}
     *         normally terminates the process;
     *         otherwise, {@link #destroy} forcibly terminates the process
     */
    boolean supportsNormalTermination();

    /**
     * Requests the process to be killed.
     * Whether the process represented by this {@code ProcessHandle} object is
     * {@link #supportsNormalTermination normally terminated} or not is
     * implementation dependent.
     * Forcible process destruction is defined as the immediate termination of the
     * process, whereas normal termination allows the process to shut down cleanly.
     * If the process is not alive, no action is taken.
     * The operating system access controls may prevent the process
     * from being killed.
     * <p>
     * The {@link java.util.concurrent.CompletableFuture} from {@link #onExit} is
     * {@link java.util.concurrent.CompletableFuture#complete completed}
     * when the process has terminated.
     * <p>
     * Note: The process may not terminate immediately.
     * For example, {@code isAlive()} may return true for a brief period
     * after {@code destroy()} is called.
     *
     * @return {@code true} if termination was successfully requested,
     *         otherwise {@code false}
     * @throws IllegalStateException if the process is the current process
     */
    boolean destroy();

    /**
     * Requests the process to be killed forcibly.
     * The process represented by this {@code ProcessHandle} object is
     * forcibly terminated.
     * Forcible process destruction is defined as the immediate termination of the
     * process, whereas normal termination allows the process to shut down cleanly.
     * If the process is not alive, no action is taken.
     * The operating system access controls may prevent the process
     * from being killed.
     * <p>
     * The {@link java.util.concurrent.CompletableFuture} from {@link #onExit} is
     * {@link java.util.concurrent.CompletableFuture#complete completed}
     * when the process has terminated.
     * <p>
     * Note: The process may not terminate immediately.
     * For example, {@code isAlive()} may return true for a brief period
     * after {@code destroyForcibly()} is called.
     *
     * @return {@code true} if termination was successfully requested,
     *         otherwise {@code false}
     * @throws IllegalStateException if the process is the current process
     */
    boolean destroyForcibly();

    /**
     * Tests whether the process represented by this {@code ProcessHandle} is alive.
     * Process termination is implementation and operating system specific.
     * The process is considered alive as long as the PID is valid.
     *
     * @return {@code true} if the process represented by this
     *         {@code ProcessHandle} object has not yet terminated
     */
    boolean isAlive();

    /**
     * Returns a hash code value for this ProcessHandle.
     * The hashcode value follows the general contract for {@link Object#hashCode()}.
     * The value is a function of the {@link #pid pid()} value and
     * may be a function of additional information to uniquely identify the process.
     * If two ProcessHandles are equal according to the {@link #equals(Object) equals}
     * method, then calling the hashCode method on each of the two objects
     * must produce the same integer result.
     *
     * @return a hash code value for this object
     */
    @Override
    int hashCode();

    /**
     * Returns {@code true} if {@code other} object is non-null, is of the
     * same implementation, and represents the same system process;
     * otherwise it returns {@code false}.
     * @implNote
     * It is implementation specific whether ProcessHandles with the same PID
     * represent the same system process. ProcessHandle implementations
     * should contain additional information to uniquely identify the process.
     * For example, the start time of the process could be used
     * to determine if the PID has been re-used.
     * The implementation of {@code equals} should return {@code true} for two
     * ProcessHandles with the same PID unless there is information to
     * distinguish them.
     *
     * @param other another object
     * @return {@code true} if the {@code other} object is non-null,
     *         is of the same implementation class and represents
     *         the same system process; otherwise returns {@code false}
     */
    @Override
    boolean equals(Object other);

    /**
     * Compares this ProcessHandle with the specified ProcessHandle for order.
     * The order is not specified, but is consistent with {@link Object#equals},
     * which returns {@code true} if and only if two instances of ProcessHandle
     * are of the same implementation and represent the same system process.
     * Comparison is only supported among objects of same implementation.
     * If attempt is made to mutually compare two different implementations
     * of {@link ProcessHandle}s, {@link ClassCastException} is thrown.
     *
     * @param other the ProcessHandle to be compared
     * @return a negative integer, zero, or a positive integer as this object
     * is less than, equal to, or greater than the specified object.
     * @throws NullPointerException if the specified object is null
     * @throws ClassCastException if the specified object is not of same class
     *         as this object
     */
    @Override
    int compareTo(ProcessHandle other);

}
