// 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.util;

import com.google.common.base.Objects;
import java.util.Collection;
import java.util.HashMap;

/**
 *  <p>Anything marked FAILURE is generally from a problem with the source code
 *  under consideration.  In these cases, a re-run in an identical client should
 *  produce an identical return code all things being constant.
 *
 *  <p>Anything marked as an ERROR is generally a problem unrelated to the
 *  source code itself.  It is either something wrong with the user's command
 *  line or the user's machine or environment.
 *
 *  <p>Note that these exit codes should be kept consistent with the codes
 *  returned by Blaze's launcher in //devtools/blaze/main:blaze.cc
 */
public class ExitCode {
  // Tracks all exit codes defined here and elsewhere in Bazel.
  private static final HashMap<Integer, ExitCode> exitCodeRegistry = new HashMap<>();

  public static final ExitCode SUCCESS = ExitCode.create(0, "SUCCESS");
  public static final ExitCode BUILD_FAILURE = ExitCode.create(1, "BUILD_FAILURE");
  public static final ExitCode PARSING_FAILURE = ExitCode.createUnregistered(1, "PARSING_FAILURE");
  public static final ExitCode COMMAND_LINE_ERROR = ExitCode.create(2, "COMMAND_LINE_ERROR");
  public static final ExitCode TESTS_FAILED = ExitCode.create(3, "TESTS_FAILED");
  public static final ExitCode PARTIAL_ANALYSIS_FAILURE =
      ExitCode.createUnregistered(3, "PARTIAL_ANALYSIS_FAILURE");
  public static final ExitCode NO_TESTS_FOUND = ExitCode.create(4, "NO_TESTS_FOUND");
  public static final ExitCode RUN_FAILURE = ExitCode.create(6, "RUN_FAILURE");
  public static final ExitCode ANALYSIS_FAILURE = ExitCode.create(7, "ANALYSIS_FAILURE");
  public static final ExitCode INTERRUPTED = ExitCode.create(8, "INTERRUPTED");

  public static final ExitCode REMOTE_ENVIRONMENTAL_ERROR =
      ExitCode.createInfrastructureFailure(32, "REMOTE_ENVIRONMENTAL_ERROR");
  public static final ExitCode OOM_ERROR = ExitCode.createInfrastructureFailure(33, "OOM_ERROR");

  public static final ExitCode REMOTE_ERROR =
      ExitCode.createInfrastructureFailure(34, "REMOTE_ERROR");
  public static final ExitCode LOCAL_ENVIRONMENTAL_ERROR =
      ExitCode.createInfrastructureFailure(36, "LOCAL_ENVIRONMENTAL_ERROR");
  public static final ExitCode BLAZE_INTERNAL_ERROR =
      ExitCode.createInfrastructureFailure(37, "BLAZE_INTERNAL_ERROR");
  /**
   * Exit code for when uploading the BES protocol fails.
   */
  public static final ExitCode PUBLISH_ERROR =
      ExitCode.createInfrastructureFailure(38, "PUBLISH_ERROR");

  public static final ExitCode REMOTE_EXECUTOR_OVERLOADED =
      ExitCode.createInfrastructureFailure(39, "REMOTE_EXECUTOR_OVERLOADED");

  public static final ExitCode RESERVED = ExitCode.createInfrastructureFailure(40, "RESERVED");

  /*
    exit codes [50..60] and 253 are reserved for site specific wrappers to Bazel.
   */

  /**
   * Creates and returns an ExitCode.  Requires a unique exit code number.
   *
   * @param code the int value for this exit code
   * @param name a human-readable description
   */
  public static ExitCode create(int code, String name) {
    return new ExitCode(code, name, /*infrastructureFailure=*/false, /*register=*/true);
  }

  /**
   * Creates and returns an ExitCode that represents an infrastructure failure.
   *
   * @param code the int value for this exit code
   * @param name a human-readable description
   */
  public static ExitCode createInfrastructureFailure(int code, String name) {
    return new ExitCode(code, name, /*infrastructureFailure=*/true, /*register=*/true);
  }

  /**
   * Creates and returns an ExitCode that has the same numeric code as another ExitCode. This is to
   * allow the duplicate error codes listed above to be registered, but is private to prevent other
   * users from creating duplicate error codes in the future.
   *
   * @param code the int value for this exit code
   * @param name a human-readable description
   */
  private static ExitCode createUnregistered(int code, String name) {
    return new ExitCode(code, name, /*infrastructureFailure=*/false, /*register=*/false);
  }

  /**
   * Add the given exit code to the registry.
   *
   * @param exitCode the exit code to register
   * @throws IllegalStateException if the numeric exit code is already in the registry.
   */
  private static void register(ExitCode exitCode) {
    synchronized (exitCodeRegistry) {
      int codeNum = exitCode.getNumericExitCode();
      if (exitCodeRegistry.containsKey(codeNum)) {
        throw new IllegalStateException(
            "Exit code " + codeNum + " (" + exitCode.name + ") already registered");
      }
      exitCodeRegistry.put(codeNum, exitCode);
    }
  }

  /**
   * Returns all registered ExitCodes.
   */
  public static Collection<ExitCode> values() {
    synchronized (exitCodeRegistry) {
      return exitCodeRegistry.values();
    }
  }

  private final int numericExitCode;
  private final String name;
  private final boolean infrastructureFailure;

  /**
   * Whenever a new exit code is created, it is registered (to prevent exit codes with identical
   * numeric codes from being created).  However, there are some exit codes in this file that have
   * duplicate numeric codes, so these are not registered.
   */
  private ExitCode(int exitCode, String name, boolean infrastructureFailure, boolean register) {
    this.numericExitCode = exitCode;
    this.name = name;
    this.infrastructureFailure = infrastructureFailure;
    if (register) {
      ExitCode.register(this);
    }
  }

  @Override
  public int hashCode() {
    return Objects.hashCode(numericExitCode, name, infrastructureFailure);
  }

  @Override
  public boolean equals(Object object) {
    if (object instanceof ExitCode) {
      ExitCode that = (ExitCode) object;
      return this.numericExitCode == that.numericExitCode
          && this.name.equals(that.name)
          && this.infrastructureFailure == that.infrastructureFailure;
    }
    return false;
  }

  /**
   * Returns the human-readable name for this exit code.  Not guaranteed to be stable, use the
   * numeric exit code for that.
   */
  @Override
  public String toString() {
    return name;
  }

  /**
   * Returns the error's int value.
   */
  public int getNumericExitCode() {
    return numericExitCode;
  }

  /**
   * Returns the human-readable name.
   */
  public String name() {
    return name;
  }

  /**
   * Returns true if the current exit code represents a failure of Blaze infrastructure,
   * vs. a build failure.
   */
  public boolean isInfrastructureFailure() {
    return infrastructureFailure;
  }
}
