//===-- Options.h -----------------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLDB_INTERPRETER_OPTIONS_H
#define LLDB_INTERPRETER_OPTIONS_H

#include <set>
#include <vector>

#include "lldb/Utility/Args.h"
#include "lldb/Utility/CompletionRequest.h"
#include "lldb/Utility/Status.h"
#include "lldb/lldb-defines.h"
#include "lldb/lldb-private.h"

#include "llvm/ADT/ArrayRef.h"

namespace lldb_private {

struct Option;

typedef std::vector<std::tuple<std::string, int, std::string>> OptionArgVector;
typedef std::shared_ptr<OptionArgVector> OptionArgVectorSP;

struct OptionArgElement {
  enum { eUnrecognizedArg = -1, eBareDash = -2, eBareDoubleDash = -3 };

  OptionArgElement(int defs_index, int pos, int arg_pos)
      : opt_defs_index(defs_index), opt_pos(pos), opt_arg_pos(arg_pos) {}

  int opt_defs_index;
  int opt_pos;
  int opt_arg_pos;
};

typedef std::vector<OptionArgElement> OptionElementVector;

static inline bool isprint8(int ch) {
  if (ch & 0xffffff00u)
    return false;
  return llvm::isPrint(ch);
}

/// \class Options Options.h "lldb/Interpreter/Options.h"
/// A command line option parsing protocol class.
///
/// Options is designed to be subclassed to contain all needed options for a
/// given command. The options can be parsed by calling the Parse function.
///
/// The options are specified using the format defined for the libc options
/// parsing function getopt_long_only: \code
///     #include <getopt.h>
///     int getopt_long_only(int argc, char * const *argv, const char
///     *optstring, const struct option *longopts, int *longindex);
/// \endcode
///
class Options {
public:
  Options();

  virtual ~Options();

  void BuildGetoptTable();

  void BuildValidOptionSets();

  uint32_t NumCommandOptions();

  /// Get the option definitions to use when parsing Args options.
  ///
  /// \see Args::ParseOptions (Options&)
  /// \see man getopt_long_only
  Option *GetLongOptions();

  // This gets passed the short option as an integer...
  void OptionSeen(int short_option);

  bool VerifyOptions(CommandReturnObject &result);

  // Verify that the options given are in the options table and can be used
  // together, but there may be some required options that are missing (used to
  // verify options that get folded into command aliases).
  bool VerifyPartialOptions(CommandReturnObject &result);

  void OutputFormattedUsageText(Stream &strm,
                                const OptionDefinition &option_def,
                                uint32_t output_max_columns);

  void GenerateOptionUsage(Stream &strm, CommandObject *cmd,
                           uint32_t screen_width);

  bool SupportsLongOption(const char *long_option);

  // The following two pure virtual functions must be defined by every class
  // that inherits from this class.

  virtual llvm::ArrayRef<OptionDefinition> GetDefinitions() {
    return llvm::ArrayRef<OptionDefinition>();
  }

  // Call this prior to parsing any options. This call will call the subclass
  // OptionParsingStarting() and will avoid the need for all
  // OptionParsingStarting() function instances from having to call the
  // Option::OptionParsingStarting() like they did before. This was error prone
  // and subclasses shouldn't have to do it.
  void NotifyOptionParsingStarting(ExecutionContext *execution_context);

  /// Parse the provided arguments.
  ///
  /// The parsed options are set via calls to SetOptionValue. In case of a
  /// successful parse, the function returns a copy of the input arguments
  /// with the parsed options removed. Otherwise, it returns an error.
  ///
  /// param[in] platform_sp
  ///   The platform used for option validation.  This is necessary
  ///   because an empty execution_context is not enough to get us
  ///   to a reasonable platform.  If the platform isn't given,
  ///   we'll try to get it from the execution context.  If we can't
  ///   get it from the execution context, we'll skip validation.
  ///
  /// param[in] require_validation
  ///   When true, it will fail option parsing if validation could
  ///   not occur due to not having a platform.
  llvm::Expected<Args> Parse(const Args &args,
                             ExecutionContext *execution_context,
                             lldb::PlatformSP platform_sp,
                             bool require_validation);

  llvm::Expected<Args> ParseAlias(const Args &args,
                                  OptionArgVector *option_arg_vector,
                                  std::string &input_line);

  OptionElementVector ParseForCompletion(const Args &args,
                                         uint32_t cursor_index);

  Status NotifyOptionParsingFinished(ExecutionContext *execution_context);

  /// Set the value of an option.
  ///
  /// \param[in] option_idx
  ///     The index into the "struct option" array that was returned
  ///     by Options::GetLongOptions().
  ///
  /// \param[in] option_arg
  ///     The argument value for the option that the user entered, or
  ///     nullptr if there is no argument for the current option.
  ///
  /// \param[in] execution_context
  ///     The execution context to use for evaluating the option.
  ///     May be nullptr if the option is to be evaluated outside any
  ///     particular context.
  ///
  /// \see Args::ParseOptions (Options&)
  /// \see man getopt_long_only
  virtual Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
                                ExecutionContext *execution_context) = 0;

  /// Handles the generic bits of figuring out whether we are in an option,
  /// and if so completing it.
  ///
  /// \param[in,out] request
  ///    The completion request that we need to act upon.
  ///
  /// \param[in] interpreter
  ///     The interpreter that's doing the completing.
  ///
  /// FIXME: This is the wrong return value, since we also need to
  /// make a distinction between total number of matches, and the window the
  /// user wants returned.
  ///
  /// \return
  ///     \btrue if we were in an option, \bfalse otherwise.
  bool HandleOptionCompletion(lldb_private::CompletionRequest &request,
                              OptionElementVector &option_map,
                              CommandInterpreter &interpreter);

  /// Handles the generic bits of figuring out whether we are in an option,
  /// and if so completing it.
  ///
  /// \param[in,out] request
  ///    The completion request that we need to act upon.
  ///
  /// \param[in] interpreter
  ///    The command interpreter doing the completion.
  virtual void
  HandleOptionArgumentCompletion(lldb_private::CompletionRequest &request,
                                 OptionElementVector &opt_element_vector,
                                 int opt_element_index,
                                 CommandInterpreter &interpreter);

protected:
  // This is a set of options expressed as indexes into the options table for
  // this Option.
  typedef std::set<int> OptionSet;
  typedef std::vector<OptionSet> OptionSetVector;

  std::vector<Option> m_getopt_table;
  OptionSet m_seen_options;
  OptionSetVector m_required_options;
  OptionSetVector m_optional_options;

  OptionSetVector &GetRequiredOptions() {
    BuildValidOptionSets();
    return m_required_options;
  }

  OptionSetVector &GetOptionalOptions() {
    BuildValidOptionSets();
    return m_optional_options;
  }

  bool IsASubset(const OptionSet &set_a, const OptionSet &set_b);

  size_t OptionsSetDiff(const OptionSet &set_a, const OptionSet &set_b,
                        OptionSet &diffs);

  void OptionsSetUnion(const OptionSet &set_a, const OptionSet &set_b,
                       OptionSet &union_set);

  // Subclasses must reset their option values prior to starting a new option
  // parse. Each subclass must override this function and revert all option
  // settings to default values.
  virtual void OptionParsingStarting(ExecutionContext *execution_context) = 0;

  virtual Status OptionParsingFinished(ExecutionContext *execution_context) {
    // If subclasses need to know when the options are done being parsed they
    // can implement this function to do extra checking
    Status error;
    return error;
  }
};

class OptionGroup {
public:
  OptionGroup() = default;

  virtual ~OptionGroup() = default;

  virtual llvm::ArrayRef<OptionDefinition> GetDefinitions() = 0;

  virtual Status SetOptionValue(uint32_t option_idx,
                                llvm::StringRef option_value,
                                ExecutionContext *execution_context) = 0;

  virtual void OptionParsingStarting(ExecutionContext *execution_context) = 0;

  virtual Status OptionParsingFinished(ExecutionContext *execution_context) {
    // If subclasses need to know when the options are done being parsed they
    // can implement this function to do extra checking
    Status error;
    return error;
  }
};

class OptionGroupOptions : public Options {
public:
  OptionGroupOptions()
      : Options(), m_option_defs(), m_option_infos(), m_did_finalize(false) {}

  ~OptionGroupOptions() override = default;

  /// Append options from a OptionGroup class.
  ///
  /// Append all options from \a group using the exact same option groups that
  /// each option is defined with.
  ///
  /// \param[in] group
  ///     A group of options to take option values from and copy their
  ///     definitions into this class.
  void Append(OptionGroup *group);

  /// Append options from a OptionGroup class.
  ///
  /// Append options from \a group that have a usage mask that has any bits in
  /// "src_mask" set. After the option definition is copied into the options
  /// definitions in this class, set the usage_mask to "dst_mask".
  ///
  /// \param[in] group
  ///     A group of options to take option values from and copy their
  ///     definitions into this class.
  ///
  /// \param[in] src_mask
  ///     When copying options from \a group, you might only want some of
  ///     the options to be appended to this group. This mask allows you
  ///     to control which options from \a group get added. It also allows
  ///     you to specify the same options from \a group multiple times
  ///     for different option sets.
  ///
  /// \param[in] dst_mask
  ///     Set the usage mask for any copied options to \a dst_mask after
  ///     copying the option definition.
  void Append(OptionGroup *group, uint32_t src_mask, uint32_t dst_mask);

  void Finalize();

  bool DidFinalize() { return m_did_finalize; }

  Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
                        ExecutionContext *execution_context) override;

  void OptionParsingStarting(ExecutionContext *execution_context) override;

  Status OptionParsingFinished(ExecutionContext *execution_context) override;

  llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
    assert(m_did_finalize);
    return m_option_defs;
  }

  const OptionGroup *GetGroupWithOption(char short_opt);

  struct OptionInfo {
    OptionInfo(OptionGroup *g, uint32_t i) : option_group(g), option_index(i) {}
    OptionGroup *option_group; // The group that this option came from
    uint32_t option_index;     // The original option index from the OptionGroup
  };
  typedef std::vector<OptionInfo> OptionInfos;

  std::vector<OptionDefinition> m_option_defs;
  OptionInfos m_option_infos;
  bool m_did_finalize;
};

} // namespace lldb_private

#endif // LLDB_INTERPRETER_OPTIONS_H
