//===-- TargetList.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_TARGET_TARGETLIST_H
#define LLDB_TARGET_TARGETLIST_H

#include <mutex>
#include <vector>

#include "lldb/Target/Target.h"
#include "lldb/Utility/Broadcaster.h"
#include "lldb/Utility/Iterable.h"

namespace lldb_private {

class TargetList : public Broadcaster {
private:
  friend class Debugger;

  /// Constructor
  ///
  /// The constructor for the target list is private. Clients can
  /// get ahold of of the one and only target list through the
  /// lldb_private::Debugger::GetSharedInstance().GetTargetList().
  ///
  /// \see static TargetList& lldb_private::Debugger::GetTargetList().
  TargetList(Debugger &debugger);

public:
  /// Broadcaster event bits definitions.
  enum { eBroadcastBitInterrupt = (1 << 0) };

  // These two functions fill out the Broadcaster interface:

  static ConstString &GetStaticBroadcasterClass();

  ConstString &GetBroadcasterClass() const override {
    return GetStaticBroadcasterClass();
  }

  typedef std::vector<lldb::TargetSP> collection;
  typedef LockingAdaptedIterable<collection, lldb::TargetSP, vector_adapter,
                                 std::recursive_mutex>
      TargetIterable;

  /// Create a new Target.
  ///
  /// Clients must use this function to create a Target. This allows
  /// a global list of targets to be maintained in a central location
  /// so signal handlers and other global functions can use it to
  /// locate an appropriate target to deliver asynchronous information
  /// to.
  ///
  /// \param[in] debugger
  ///     The debugger to associate this target with
  ///
  /// \param[in] user_exe_path
  ///     The main executable file for a debug target. This value
  ///     can be empty and the file can be set later using:
  ///     Target::SetExecutableModule (ModuleSP&)
  ///
  /// \param[in] triple_str
  ///     A target triple string to be used for the target. This can
  ///     be nullptr if the triple is not known or when attaching to a
  ///     process.
  ///
  /// \param[in] get_dependent_modules
  ///     Track down the dependent modules for an executable and
  ///     load those into the module list.
  ///
  /// \param[in] platform_options
  ///     A pointer to the platform options to use when creating this
  ///     target. If this value is nullptr, then the currently selected
  ///     platform will be used.
  ///
  /// \param[out] target_sp
  ///     A shared pointer to a target that will be filled in if
  ///     this call is successful.
  ///
  /// \return
  ///     An error object that indicates success or failure
  Status CreateTarget(Debugger &debugger, llvm::StringRef user_exe_path,
                      llvm::StringRef triple_str,
                      LoadDependentFiles get_dependent_modules,
                      const OptionGroupPlatform *platform_options,
                      lldb::TargetSP &target_sp);

  /// Create a new Target.
  ///
  /// Same as the function above, but used when you already know the
  /// platform you will be using
  Status CreateTarget(Debugger &debugger, llvm::StringRef user_exe_path,
                      const ArchSpec &arch,
                      LoadDependentFiles get_dependent_modules,
                      lldb::PlatformSP &platform_sp, lldb::TargetSP &target_sp);

  /// Delete a Target object from the list.
  ///
  /// When clients are done with the Target objects, this function
  /// should be called to release the memory associated with a target
  /// object.
  ///
  /// \param[in] target_sp
  ///     The shared pointer to a target.
  ///
  /// \return
  ///     Returns \b true if the target was successfully removed from
  ///     from this target list, \b false otherwise. The client will
  ///     be left with the last remaining shared pointer to the target
  ///     in \a target_sp which can then be properly released.
  bool DeleteTarget(lldb::TargetSP &target_sp);

  int GetNumTargets() const;

  lldb::TargetSP GetTargetAtIndex(uint32_t index) const;

  uint32_t GetIndexOfTarget(lldb::TargetSP target_sp) const;

  /// Find the target that contains has an executable whose path
  /// matches \a exe_file_spec, and whose architecture matches
  /// \a arch_ptr if arch_ptr is not nullptr.
  ///
  /// \param[in] exe_file_spec
  ///     A file spec containing a basename, or a full path (directory
  ///     and basename). If \a exe_file_spec contains only a filename
  ///     (empty GetDirectory() value) then matching will be done
  ///     solely based on the filenames and directories won't be
  ///     compared. If \a exe_file_spec contains a filename and a
  ///     directory, then both must match.
  ///
  /// \param[in] exe_arch_ptr
  ///     If not nullptr then the architecture also needs to match, else
  ///     the architectures will be compared.
  ///
  /// \return
  ///     A shared pointer to a target object. The returned shared
  ///     pointer will contain nullptr if no target objects have a
  ///     executable whose full or partial path matches
  ///     with a matching process ID.
  lldb::TargetSP FindTargetWithExecutableAndArchitecture(
      const FileSpec &exe_file_spec,
      const ArchSpec *exe_arch_ptr = nullptr) const;

  /// Find the target that contains a process with process ID \a
  /// pid.
  ///
  /// \param[in] pid
  ///     The process ID to search our target list for.
  ///
  /// \return
  ///     A shared pointer to a target object. The returned shared
  ///     pointer will contain nullptr if no target objects own a process
  ///     with a matching process ID.
  lldb::TargetSP FindTargetWithProcessID(lldb::pid_t pid) const;

  lldb::TargetSP FindTargetWithProcess(lldb_private::Process *process) const;

  lldb::TargetSP GetTargetSP(Target *target) const;

  /// Send an async interrupt to one or all processes.
  ///
  /// Find the target that contains the process with process ID \a
  /// pid and send a LLDB_EVENT_ASYNC_INTERRUPT event to the process's
  /// event queue.
  ///
  /// \param[in] pid
  ///     The process ID to search our target list for, if \a pid is
  ///     LLDB_INVALID_PROCESS_ID, then the interrupt will be sent to
  ///     all processes.
  ///
  /// \return
  ///     The number of async interrupts sent.
  uint32_t SendAsyncInterrupt(lldb::pid_t pid = LLDB_INVALID_PROCESS_ID);

  uint32_t SignalIfRunning(lldb::pid_t pid, int signo);

  void SetSelectedTarget(uint32_t index);

  void SetSelectedTarget(const lldb::TargetSP &target);

  lldb::TargetSP GetSelectedTarget();

  TargetIterable Targets() {
    return TargetIterable(m_target_list, m_target_list_mutex);
  }

private:
  collection m_target_list;
  mutable std::recursive_mutex m_target_list_mutex;
  uint32_t m_selected_target_idx;

  static Status CreateTargetInternal(
      Debugger &debugger, llvm::StringRef user_exe_path,
      llvm::StringRef triple_str, LoadDependentFiles load_dependent_files,
      const OptionGroupPlatform *platform_options, lldb::TargetSP &target_sp);

  static Status CreateTargetInternal(Debugger &debugger,
                                     llvm::StringRef user_exe_path,
                                     const ArchSpec &arch,
                                     LoadDependentFiles get_dependent_modules,
                                     lldb::PlatformSP &platform_sp,
                                     lldb::TargetSP &target_sp);

  void AddTargetInternal(lldb::TargetSP target_sp, bool do_select);

  void SetSelectedTargetInternal(uint32_t index);

  TargetList(const TargetList &) = delete;
  const TargetList &operator=(const TargetList &) = delete;
};

} // namespace lldb_private

#endif // LLDB_TARGET_TARGETLIST_H
