// 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.
#ifndef BAZEL_SRC_MAIN_CPP_STARTUP_OPTIONS_H_
#define BAZEL_SRC_MAIN_CPP_STARTUP_OPTIONS_H_

#if defined(__APPLE__)
#include <sys/qos.h>
#endif

#include <map>
#include <memory>
#include <set>
#include <string>
#include <utility>
#include <vector>

#include "src/main/cpp/util/exit_code.h"

namespace blaze {

class WorkspaceLayout;

// Represents a single startup flag (or startup option).
class StartupFlag {
 public:
  virtual ~StartupFlag() = 0;
  virtual bool NeedsParameter() const = 0;
  virtual bool IsValid(const std::string& arg) const = 0;
};

// A startup flag that doesn't expect a value.
// For instance, NullaryStartupFlag("master_bazelrc") is used to represent
// "--master_bazelrc" and "--nomaster_bazelrc".
class NullaryStartupFlag : public StartupFlag {
 public:
  NullaryStartupFlag(const std::string& name) : name_(name) {}
  bool IsValid(const std::string& arg) const override;
  bool NeedsParameter() const override;

 private:
  const std::string name_;
};

// A startup flag that expects a value.
// For instance, UnaryStartupFlag("bazelrc") is used to represent
// "--bazelrc=foo" or "--bazelrc foo".
class UnaryStartupFlag : public StartupFlag {
 public:
  UnaryStartupFlag(const std::string& name) : name_(name) {}
  bool IsValid(const std::string& arg) const override;
  bool NeedsParameter() const override;

 private:
  const std::string name_;
};

// A startup flag tagged with its origin, either an rc file or the empty
// string for the ones specified in the command line.
// For instance, RcStartupFlag("somepath/.bazelrc", "--foo") is used to
// represent that the line "startup --foo" was found when parsing
// "somepath/.bazelrc".
struct RcStartupFlag {
  const std::string source;
  const std::string value;
  RcStartupFlag(const std::string& source_arg,
                const std::string& value_arg)
      : source(source_arg), value(value_arg) {}
};

// This class defines the startup options accepted by all versions Bazel, and
// holds the parsed values. These options and their defaults must be kept in
// sync with those in
// src/main/java/com/google/devtools/build/lib/runtime/BlazeServerStartupOptions.java.
// The latter are (usually) purely decorative (they affect the help message,
// which displays the defaults).  The actual defaults are defined
// in the constructor.
//
// TODO(bazel-team): The encapsulation is not quite right -- there are some
// places in blaze.cc where some of these fields are explicitly modified. Their
// names also don't conform to the style guide.
class StartupOptions {
 public:
  virtual ~StartupOptions();

  // Process an ordered list of RcStartupFlags using ProcessArg.
  blaze_exit_code::ExitCode ProcessArgs(
      const std::vector<RcStartupFlag>& rcstartup_flags,
      std::string *error);

  // Adds any other options needed to result.
  //
  // TODO(jmmv): Now that we support site-specific options via subclasses of
  // StartupOptions, the "ExtraOptions" concept makes no sense; remove it.
  virtual void AddExtraOptions(std::vector<std::string> *result) const;

  // Once startup options have been parsed, warn the user if certain options
  // might combine in surprising ways.
  virtual void MaybeLogStartupOptionWarnings() const = 0;

  // Returns the path to the JVM. This should be called after parsing
  // the startup options.
  virtual std::string GetJvm() const;

  // Returns the executable used to start the Blaze server, typically the given
  // JVM.
  virtual std::string GetExe(const std::string &jvm,
                             const std::string &jar_path) const;

  // Adds JVM prefix flags to be set. These will be added before all other
  // JVM flags.
  virtual void AddJVMArgumentPrefix(const std::string &javabase,
                                    std::vector<std::string> *result) const;

  // Adds JVM suffix flags. These will be added after all other JVM flags, and
  // just before the Blaze server startup flags.
  virtual void AddJVMArgumentSuffix(const std::string &real_install_dir,
                                    const std::string &jar_path,
                                    std::vector<std::string> *result) const;

  // Adds JVM tuning flags for Blaze.
  //
  // Returns the exit code after this operation. "error" will be set to a
  // descriptive string for any value other than blaze_exit_code::SUCCESS.
  blaze_exit_code::ExitCode AddJVMArguments(
      const std::string &server_javabase, std::vector<std::string> *result,
      const std::vector<std::string> &user_options, std::string *error) const;

  // Checks whether the argument is a valid nullary option.
  // E.g. --master_bazelrc, --nomaster_bazelrc.
  bool IsNullary(const std::string& arg) const;

  // Checks whether the argument is a valid unary option.
  // E.g. --blazerc=foo, --blazerc foo.
  bool IsUnary(const std::string& arg) const;

  std::string GetLowercaseProductName() const;

  // The capitalized name of this binary.
  const std::string product_name;

  // If supplied, alternate location to write the blaze server's jvm's stdout.
  // Otherwise a default path in the output base is used.
  std::string server_jvm_out;

  // Blaze's output base.  Everything is relative to this.  See
  // the BlazeDirectories Java class for details.
  std::string output_base;

  // Installation base for a specific release installation.
  std::string install_base;

  // The toplevel directory containing Blaze's output.  When Blaze is
  // run by a test, we use TEST_TMPDIR, simplifying the correct
  // hermetic invocation of Blaze from tests.
  std::string output_root;

  // Blaze's output_user_root. Used only for computing install_base and
  // output_base.
  std::string output_user_root;

  // Override more finegrained rc file flags and ignore them all.
  bool ignore_all_rc_files;

  // Whether to put the execroot at $OUTPUT_BASE/$WORKSPACE_NAME (if false) or
  // $OUTPUT_BASE/execroot/$WORKSPACE_NAME (if true).
  bool deep_execroot;

  // Block for the Blaze server lock. Otherwise,
  // quit with non-0 exit code if lock can't
  // be acquired immediately.
  bool block_for_lock;

  bool host_jvm_debug;

  std::string host_jvm_profile;

  std::vector<std::string> host_jvm_args;

  bool batch;

  // From the man page: "This policy is useful for workloads that are
  // non-interactive, but do not want to lower their nice value, and for
  // workloads that want a deterministic scheduling policy without
  // interactivity causing extra preemptions (between the workload's tasks)."
  bool batch_cpu_scheduling;

  // If negative, don't mess with ionice. Otherwise, set a level from 0-7
  // for best-effort scheduling. 0 is highest priority, 7 is lowest.
  int io_nice_level;

  int max_idle_secs;

  bool shutdown_on_low_sys_mem;

  bool oom_more_eagerly;

  int oom_more_eagerly_threshold;

  bool write_command_log;

  // If true, Blaze will listen to OS-level file change notifications.
  bool watchfs;

  // Temporary flag for enabling EventBus exceptions to be fatal.
  bool fatal_event_bus_exceptions;

  // A string to string map specifying where each option comes from. If the
  // value is empty, it was on the command line, if it is a string, it comes
  // from a blazerc file, if a key is not present, it is the default.
  std::map<std::string, std::string> option_sources;

  // Returns the embedded JDK, or an empty string.
  std::string GetEmbeddedJavabase() const;

  // Returns the GetHostJavabase. This should be called after parsing
  // the --server_javabase option.
  std::string GetServerJavabase() const;

  // Returns the explicit value of the --server_javabase startup option or the
  // empty string if it was not specified on the command line.
  std::string GetExplicitServerJavabase() const;

  // Port to start up the gRPC command server on. If 0, let the kernel choose.
  int command_port;

  // Connection timeout for each gRPC connection attempt.
  int connect_timeout_secs;

  // Invocation policy proto, or an empty string.
  std::string invocation_policy;
  // Invocation policy can only be specified once.
  bool have_invocation_policy_;

  // Whether to output addition debugging information in the client.
  bool client_debug;

  // Value of the java.util.logging.FileHandler.formatter Java property.
  std::string java_logging_formatter;

  bool expand_configs_in_place;

  // The hash function to use when computing file digests.
  std::string digest_function;

  bool idle_server_tasks;

  // The startup options as received from the user and rc files, tagged with
  // their origin. This is populated by ProcessArgs.
  std::vector<RcStartupFlag> original_startup_options_;

#if defined(__APPLE__)
  // The QoS class to apply to the Bazel server process.
  qos_class_t macos_qos_class;
#endif

  // Whether to raise the soft coredump limit to the hard one or not.
  bool unlimit_coredumps;

 protected:
  // Constructor for subclasses only so that site-specific extensions of this
  // class can override the product name.  The product_name must be the
  // capitalized version of the name, as in "Bazel".
  StartupOptions(const std::string &product_name,
                 const WorkspaceLayout *workspace_layout);

  // Checks extra fields when processing arg.
  //
  // Returns the exit code after processing the argument. "error" will contain
  // a descriptive string for any return value other than
  // blaze_exit_code::SUCCESS.
  //
  // TODO(jmmv): Now that we support site-specific options via subclasses of
  // StartupOptions, the "ExtraOptions" concept makes no sense; remove it.
  virtual blaze_exit_code::ExitCode ProcessArgExtra(
      const char *arg, const char *next_arg, const std::string &rcfile,
      const char **value, bool *is_processed, std::string *error) = 0;

  // Returns the absolute path to the user's local JDK install, to be used as
  // the default target javabase and as a fall-back host_javabase. This is not
  // the embedded JDK.
  virtual std::string GetSystemJavabase() const;

  // Adds JVM logging-related flags for Bazel.
  //
  // This is called by StartupOptions::AddJVMArguments and is a separate method
  // so that subclasses of StartupOptions can override it.
  virtual void AddJVMLoggingArguments(std::vector<std::string> *result) const;

  // Adds JVM memory tuning flags for Bazel.
  //
  // This is called by StartupOptions::AddJVMArguments and is a separate method
  // so that subclasses of StartupOptions can override it.
  virtual blaze_exit_code::ExitCode AddJVMMemoryArguments(
      const std::string &server_javabase, std::vector<std::string> *result,
      const std::vector<std::string> &user_options, std::string *error) const;

  void RegisterUnaryStartupFlag(const std::string& flag_name);

  void RegisterNullaryStartupFlag(const std::string& flag_name);

 private:
  // Parses a single argument, either from the command line or from the .blazerc
  // "startup" options.
  //
  // rcfile should be an empty string if the option being parsed does not come
  // from a blazerc.
  //
  // Sets "is_space_separated" true if arg is unary and uses the "--foo bar"
  // style, so its value is in next_arg.
  //
  // Sets "is_space_separated" false if arg is either nullary
  // (e.g. "--[no]batch") or is unary but uses the "--foo=bar" style.
  //
  // Returns the exit code after processing the argument. "error" will contain
  // a descriptive string for any return value other than
  // blaze_exit_code::SUCCESS.
  blaze_exit_code::ExitCode ProcessArg(const std::string &arg,
                                       const std::string &next_arg,
                                       const std::string &rcfile,
                                       bool *is_space_separated,
                                       std::string *error);

  // The server javabase as provided on the commandline.
  std::string explicit_server_javabase_;

  // The server javabase to be used (computed lazily).
  mutable std::string default_server_javabase_;

  // Contains the collection of startup flags that Bazel accepts.
  std::set<std::unique_ptr<StartupFlag>> valid_startup_flags;
};

}  // namespace blaze

#endif  // BAZEL_SRC_MAIN_CPP_STARTUP_OPTIONS_H_
