// Copyright 2020 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_DEBUG_ADAPTER_CONTEXT_H_
#define SRC_DEVELOPER_DEBUG_ZXDB_DEBUG_ADAPTER_CONTEXT_H_

#include <cstdint>
#include <utility>

#include <dap/protocol.h>
#include <dap/session.h>

#include "src/developer/debug/shared/stream_buffer.h"
#include "src/developer/debug/zxdb/client/frame.h"
#include "src/developer/debug/zxdb/client/process_observer.h"
#include "src/developer/debug/zxdb/client/session.h"
#include "src/developer/debug/zxdb/client/thread_observer.h"
#include "src/developer/debug/zxdb/common/err.h"
#include "src/developer/debug/zxdb/expr/format_node.h"
#include "src/lib/fxl/memory/weak_ptr.h"

namespace zxdb {

class Session;
class Breakpoint;

class DebugAdapterServer;
class DebugAdapterReader;
class DebugAdapterWriter;

// Types of variables reported in variables request.
enum class VariablesType {
  kLocal = 0,
  kArguments,
  kRegister,
  kChildVariable,
  kVariablesTypeCount,  // Keep this in the end always
};

struct VariablesRecord {
  int64_t frame_id;
  VariablesType type = VariablesType::kVariablesTypeCount;
  // Fields to store children information corresponding to the record so that subsequent variables
  // request can be processed. Store the format node in `parent` if children exist. If `parent`'s
  // child has children, store a weak pointer to it in `child`.
  std::unique_ptr<FormatNode> parent;
  fxl::WeakPtr<FormatNode> child;
};

// Handles processing requests from debug adapter client with help from zxdb client session and dap
// library.
// Note: All methods in this class need to be executed on main thread to avoid concurrency bugs.
class DebugAdapterContext : public ThreadObserver, ProcessObserver {
 public:
  using DestroyConnectionCallback = std::function<void()>;

  explicit DebugAdapterContext(Session* session, debug_ipc::StreamBuffer* stream);
  virtual ~DebugAdapterContext();

  Session* session() { return session_; }
  dap::Session& dap() { return *dap_; }
  bool supports_run_in_terminal() { return supports_run_in_terminal_; };

  // Notification about the stream.
  void OnStreamReadable();

  // Callback to delete the connection and hence this context. This callback will be posted on
  // message loop.
  void set_destroy_connection_callback(DestroyConnectionCallback cb) {
    destroy_connection_cb_ = std::move(cb);
  }

  // ThreadObserver implementation:
  void DidCreateThread(Thread* thread) override;
  void WillDestroyThread(Thread* thread) override;
  void OnThreadStopped(Thread* thread, const StopInfo& info) override;
  void OnThreadFramesInvalidated(Thread* thread) override;

  // ProcessObserver implementation:
  void DidCreateProcess(Process* process, bool autoattached_to_new_process,
                        uint64_t timestamp) override;
  void WillDestroyProcess(Process* process, DestroyReason reason, int exit_code,
                          uint64_t timestamp) override;

  Thread* GetThread(uint64_t koid);

  // Checks if thread is in stopped state; returns error if not stopped.
  // `thread` can be nullptr, in which case an error is returned.
  Err CheckStoppedThread(Thread* thread);

  // Helper methods to get/set frame to ID mapping
  int64_t IdForFrame(Frame* frame, int stack_index);
  Frame* FrameforId(int64_t id);
  void DeleteFrameIdsForThread(Thread* thread);

  // Helper methods to get/set variables references
  int64_t IdForVariables(int64_t frame_id, VariablesType type,
                         std::unique_ptr<FormatNode> parent = nullptr,
                         fxl::WeakPtr<FormatNode> child = nullptr);
  VariablesRecord* VariablesRecordForID(int64_t id);
  void DeleteVariablesIdsForFrameId(int64_t id);

  // Helper methods to get/set breakpoint to source file mapping.
  void StoreBreakpointForSource(const std::string& source, Breakpoint* bp);
  std::vector<fxl::WeakPtr<Breakpoint>>* GetBreakpointsForSource(const std::string& source);

  // TODO(fxbug.dev/69392): These 2 method deletes all breakpoints added by the debug adapter.
  // Breakpoints added from console are not deleted.
  void DeleteBreakpointsForSource(const std::string& source);
  void DeleteAllBreakpoints();

 private:
  Session* const session_;
  const std::unique_ptr<dap::Session> dap_;
  std::shared_ptr<DebugAdapterReader> reader_;
  std::shared_ptr<DebugAdapterWriter> writer_;

  bool supports_run_in_terminal_ = false;
  bool supports_invalidate_event_ = false;
  bool init_done_ = false;

  struct FrameRecord {
    uint64_t thread_koid = 0;
    int stack_index = 0;
  };
  std::map<int64_t, FrameRecord> id_to_frame_;
  int64_t next_frame_id_ = 1;

  std::map<int64_t, VariablesRecord> id_to_variables_;
  int64_t next_variables_id_ = 1;

  DestroyConnectionCallback destroy_connection_cb_;

  // This mapping is temporarily added to store all breakpoints added by debug adapter client. Once
  // http://fxbug.dev/69392 is fixed, this can removed in favor of using System::GetBreakpoints API
  // i.e. with breakpoint event, debug adapter client can be made aware of additional breakpoints
  // (from say zxdb console) and hence breakpoint list maintained by system will be identical to
  // this map in terms of the entries. One could traverse the entire system breakpoint list to get
  // breakpoints related to a source file instead of having to maintain a separate map.
  std::map<std::string, std::vector<fxl::WeakPtr<Breakpoint>>> source_to_bp_;

  void Init();
};

class DebugAdapterReader : public dap::Reader {
 public:
  explicit DebugAdapterReader(debug_ipc::StreamBuffer* stream) : stream_(stream) {}
  size_t read(void* buffer, size_t n) override {
    if (!stream_) {
      return 0;
    }
    auto ret = stream_->Read(static_cast<char*>(buffer), n);
    return ret;
  }
  bool isOpen() override { return !!stream_; }

  void close() override { stream_ = nullptr; }

 private:
  debug_ipc::StreamBuffer* stream_ = nullptr;
};

class DebugAdapterWriter : public dap::Writer {
 public:
  explicit DebugAdapterWriter(debug_ipc::StreamBuffer* stream) : stream_(stream) {}
  bool write(const void* buffer, size_t n) override {
    if (!stream_) {
      return false;
    }
    stream_->Write(
        std::vector<char>(static_cast<const char*>(buffer), static_cast<const char*>(buffer) + n));
    return true;
  }
  bool isOpen() override { return !!stream_; }

  void close() override { stream_ = nullptr; }

 private:
  debug_ipc::StreamBuffer* stream_ = nullptr;
};

}  // namespace zxdb

#endif  // SRC_DEVELOPER_DEBUG_ZXDB_DEBUG_ADAPTER_CONTEXT_H_
