// Copyright 2014 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package com.google.devtools.build.lib.shell;

/**
 * Represents the termination status of a command.  {@link Process#waitFor} is
 * not very precisely specified, so this class encapsulates the interpretation
 * of values returned by it.
 *
 * Caveat: due to the lossy encoding, it's not always possible to accurately
 * distinguish signal and exit cases.  In particular, processes that exit with
 * a value within the interval [129, 191] will be mistaken for having been
 * terminated by a signal.
 *
 * Instances are immutable.
 */
public final class TerminationStatus {

  private final int waitResult;
  private final boolean timedout;

  /**
   * Values taken from the glibc strsignal(3) function.
   */
  private static final String[] SIGNAL_STRINGS = {
    null,
    "Hangup",
    "Interrupt",
    "Quit",
    "Illegal instruction",
    "Trace/breakpoint trap",
    "Aborted",
    "Bus error",
    "Floating point exception",
    "Killed",
    "User defined signal 1",
    "Segmentation fault",
    "User defined signal 2",
    "Broken pipe",
    "Alarm clock",
    "Terminated",
    "Stack fault",
    "Child exited",
    "Continued",
    "Stopped (signal)",
    "Stopped",
    "Stopped (tty input)",
    "Stopped (tty output)",
    "Urgent I/O condition",
    "CPU time limit exceeded",
    "File size limit exceeded",
    "Virtual timer expired",
    "Profiling timer expired",
    "Window changed",
    "I/O possible",
    "Power failure",
    "Bad system call",
  };

  private static String getSignalString(int signum) {
    return signum > 0 && signum < SIGNAL_STRINGS.length
        ? SIGNAL_STRINGS[signum]
        : "Signal " + signum;
  }

  /**
   * Construct a TerminationStatus instance from a Process waitFor code.
   *
   * @param waitResult the value returned by {@link java.lang.Process#waitFor}.
   */
  public TerminationStatus(int waitResult, boolean timedout) {
    this.waitResult = waitResult;
    this.timedout = timedout;
  }

  /**
   * Returns the "raw" result returned by Process.waitFor. This value is not
   * precisely defined, and is not to be confused with the value passed to
   * exit(2) by the subprocess.  Use getTerminationStatus() instead.
   */
  int getRawResult() {
    return waitResult;
  }

  /**
   * Returns true iff the process exited with code 0.
   */
  public boolean success() {
    return exited() && getExitCode() == 0;
  }

  // We're relying on undocumented behaviour of Process.waitFor, specifically
  // that waitResult is the exit status when the process returns normally, or
  // 128+signalnumber when the process is terminated by a signal.  We further
  // assume that value signal numbers fall in the interval [1, 63].
  private static final int SIGNAL_1  = 128 + 1;
  private static final int SIGNAL_63 = 128 + 63;

  /**
   * Returns true iff the process exited normally.
   */
  public boolean exited() {
    return !timedout && (waitResult < SIGNAL_1 || waitResult > SIGNAL_63);
  }

  /**
   * Returns true if the process timed out.
   */
  public boolean timedout() {
    return timedout;
  }

  /**
   * Returns the exit code of the subprocess.  Undefined if exited() is false.
   */
  public int getExitCode() {
    if (!exited()) {
      throw new IllegalStateException("getExitCode() not defined");
    }
    return waitResult;
  }

  /**
   * Returns the number of the signal that terminated the process.  Undefined
   * if exited() returns true.
   */
  public int getTerminatingSignal() {
    if (exited() || timedout) {
      throw new IllegalStateException("getTerminatingSignal() not defined");
    }
    return waitResult - SIGNAL_1 + 1;
  }

  /**
   * Returns a short string describing the termination status.
   * e.g. "Exit 1" or "Hangup".
   */
  public String toShortString() {
    return exited() ? "Exit " + getExitCode()
      : timedout ? "Timeout"
      : getSignalString(getTerminatingSignal());
  }

  @Override
  public String toString() {
    if (exited()) {
      return "Process exited with status " + getExitCode();
    } else if (timedout) {
      return "Timed out";
    } else {
      return "Process terminated by signal " + getTerminatingSignal();
    }
  }

  @Override
  public int hashCode() {
    return waitResult;
  }

  @Override
  public boolean equals(Object other) {
    return other instanceof TerminationStatus &&
      ((TerminationStatus) other).waitResult == this.waitResult;
  }
}
