// 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 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, bool autoattached, 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;

  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_
