// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef SRC_DEVELOPER_DEBUG_ZXDB_CLIENT_BREAKPOINT_IMPL_H_
#define SRC_DEVELOPER_DEBUG_ZXDB_CLIENT_BREAKPOINT_IMPL_H_

#include <map>

#include "src/developer/debug/zxdb/client/breakpoint.h"
#include "src/developer/debug/zxdb/client/breakpoint_action.h"
#include "src/developer/debug/zxdb/client/process_observer.h"
#include "src/developer/debug/zxdb/client/system_observer.h"
#include "src/developer/debug/zxdb/client/target_observer.h"
#include "src/developer/debug/zxdb/client/thread_observer.h"
#include "src/developer/debug/zxdb/symbols/resolve_options.h"
#include "src/lib/fxl/memory/weak_ptr.h"

namespace debug_ipc {
struct BreakpointStats;
}

namespace zxdb {

class BreakpointLocationImpl;
class Location;

class BreakpointImpl : public Breakpoint,
                       public TargetObserver,
                       public ProcessObserver,
                       public ThreadObserver {
 public:
  // The controller can be null in which case it will perform the default behavior. The controller
  // must outlive the breakpoint.
  BreakpointImpl(Session* session, bool is_internal);
  ~BreakpointImpl() override;

  // This flag doesn't control anything in the breakpoint but is stored here for the use of external
  // consumers. Internal breakpoints are set by the debugger internally as part of implementing
  // other features such as stepping. They should not be shown to the user.
  bool is_internal() const { return is_internal_; }

  // Identifies this breakpoint to the backend in IPC messages. This will not change.
  uint32_t backend_id() const { return backend_id_; }

  // Breakpoint implementation:
  BreakpointSettings GetSettings() const override;
  using Breakpoint::SetSettings;  // Pull in one-arg helper.
  void SetSettings(const BreakpointSettings& settings, SetCallback cb) override;
  bool IsInternal() const override;
  std::vector<const BreakpointLocation*> GetLocations() const override;
  std::vector<BreakpointLocation*> GetLocations() override;
  debug_ipc::BreakpointStats GetStats() override;

  // Called whenever new stats are available from the debug agent.
  void UpdateStats(const debug_ipc::BreakpointStats& stats);

  // Called when the backend reports that the breakpoint has been automatically
  // removed.
  void BackendBreakpointRemoved();

 private:
  friend BreakpointLocationImpl;
  struct ProcessRecord;

  // TargetObserver.
  void WillDestroyTarget(Target* target) override;

  // ProcessObserver.
  void DidCreateProcess(Process* process, uint64_t timestamp) override;
  void WillDestroyProcess(Process* process, ProcessObserver::DestroyReason reason, int exit_code,
                          uint64_t timestamp) override;
  void DidLoadModuleSymbols(Process* process, LoadedModuleSymbols* module) override;
  void WillUnloadModuleSymbols(Process* process, LoadedModuleSymbols* module) override;

  // ThreadObserver.
  void WillDestroyThread(Thread* thread) override;

  // These functions update the debug_agent. The optional callback will be issued on confirmed
  // success or failure.
  void SyncBackend(SetCallback cb = SetCallback());
  void SendBackendAddOrChange(SetCallback cb = SetCallback());
  void SendBackendRemove(SetCallback cb = SetCallback());

  void OnAddOrChangeComplete(const Err& err, debug_ipc::AddOrChangeBreakpointReply reply,
                             SetCallback cb);
  void OnRemoveComplete(const Err& err, debug_ipc::RemoveBreakpointReply reply, SetCallback cb);

  // Notification from BreakpointLocationImpl that the enabled state has changed and the breakpoint
  // state needs to be synced.
  void DidChangeLocation();

  // Returns true if the breakpoint could possibly apply to the given process (if things like
  // symbols aren't found, it still may not necessarily apply).
  bool CouldApplyToProcess(Process* process) const;

  // Returns true if there are any enabled breakpoint locations that the backend needs to know
  // about.
  bool HasEnabledLocation() const;

  // Given a process which is new or might apply to us for the first time, Returns true if any
  // addresses were resolved.
  bool RegisterProcess(Process* process);

  // Returns the options for converting this breakpoint's input location to addresses,
  ResolveOptions GetResolveOptions() const;

  // Returns true if all input locations for this breakpoint are addesses.
  bool AllLocationsAddresses() const;

  // Helper for detecting when we're about to install a breakpoint in the starnix_kernel module.
  // This is fairly hacky, but should be good enough for most cases.
  bool IsResolvedLocationInSharedAddressSpace(Process* process,
                                              const std::vector<Location>& locations) const;

  bool is_internal_;

  // ID used to refer to this in the backend.
  const uint32_t backend_id_;

  BreakpointSettings settings_;

  debug_ipc::BreakpointStats stats_;

  // Indicates if the backend knows about this breakpoint.
  bool backend_installed_ = false;

  // Every process which this breakpoint can apply to is in this map, even if there are no addresses
  // associated with it.
  std::map<Process*, ProcessRecord> procs_;

  fxl::WeakPtrFactory<BreakpointImpl> impl_weak_factory_;

  // Set when we're a thread-scoped breakpoint and so are registered as a thread observer. There
  // are potentially a lot of threads and breakpoints, and thread-scoped breakpoints are rare, so
  // we don't regiter for these unless necessary.
  bool registered_as_thread_observer_ = false;

  FXL_DISALLOW_COPY_AND_ASSIGN(BreakpointImpl);
};

}  // namespace zxdb

#endif  // SRC_DEVELOPER_DEBUG_ZXDB_CLIENT_BREAKPOINT_IMPL_H_
