// 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.

#include "src/developer/debug/debug_agent/remote_api_adapter.h"

#include "src/developer/debug/debug_agent/remote_api.h"
#include "src/developer/debug/ipc/agent_protocol.h"
#include "src/developer/debug/ipc/message_reader.h"
#include "src/developer/debug/ipc/message_writer.h"
#include "src/developer/debug/ipc/protocol.h"
#include "src/developer/debug/shared/logging/logging.h"
#include "src/developer/debug/shared/stream_buffer.h"

namespace debug_agent {

namespace {

// Deserializes the request based on type, calls the given hander in the
// RemoteAPI, and then sends the reply back to the client.
template <typename RequestMsg, typename ReplyMsg>
void DispatchMessage(RemoteAPIAdapter* adapter,
                     void (RemoteAPI::*handler)(const RequestMsg&, ReplyMsg*),
                     std::vector<char> data, const char* type_string) {
  debug_ipc::MessageReader reader(std::move(data));

  RequestMsg request;
  uint32_t transaction_id = 0;
  if (!debug_ipc::ReadRequest(&reader, &request, &transaction_id)) {
    fprintf(stderr, "Got bad debugger %sRequest, ignoring.\n", type_string);
    return;
  }

  ReplyMsg reply;
  (adapter->api()->*handler)(request, &reply);

  debug_ipc::MessageWriter writer;
  debug_ipc::WriteReply(reply, transaction_id, &writer);

  adapter->stream()->Write(writer.MessageComplete());
}

}  // namespace

RemoteAPIAdapter::RemoteAPIAdapter(RemoteAPI* remote_api, debug::StreamBuffer* stream)
    : api_(remote_api), stream_(stream) {}

RemoteAPIAdapter::~RemoteAPIAdapter() {}

void RemoteAPIAdapter::OnStreamReadable() {
  while (true) {
    debug_ipc::MsgHeader header;
    size_t bytes_read = stream_->Peek(reinterpret_cast<char*>(&header), sizeof(header));
    if (bytes_read != sizeof(header))
      return;  // Don't have enough data for the header.
    if (!stream_->IsAvailable(header.size))
      return;  // Entire message hasn't arrived yet.

    // The message size includes the header.
    std::vector<char> buffer(header.size);
    stream_->Read(buffer.data(), header.size);

    // Range check the message type.
    if (header.type == debug_ipc::MsgHeader::Type::kNone ||
        header.type >= debug_ipc::MsgHeader::Type::kNumMessages) {
      fprintf(stderr, "Invalid message type %u, ignoring.\n", static_cast<unsigned>(header.type));
      return;
    }

// Dispatches a message type assuming the handler function name, request
// struct type, and reply struct type are all based on the message type name.
// For example, MsgHeader::Type::kFoo will call:
//   api->OnFoo(FooRequest, FooReply*);
#define DISPATCH(msg_type)                                                     \
  case debug_ipc::MsgHeader::Type::k##msg_type:                                \
    DispatchMessage<debug_ipc::msg_type##Request, debug_ipc::msg_type##Reply>( \
        this, &RemoteAPI::On##msg_type, std::move(buffer), #msg_type);         \
    break

    switch (header.type) {
      DISPATCH(AddOrChangeBreakpoint);
      DISPATCH(AddressSpace);
      DISPATCH(ConfigAgent);
      DISPATCH(Detach);
      DISPATCH(JobFilter);
      DISPATCH(Hello);
      DISPATCH(Kill);
      DISPATCH(Launch);
      DISPATCH(Modules);
      DISPATCH(Pause);
      DISPATCH(ProcessStatus);
      DISPATCH(ProcessTree);
      DISPATCH(QuitAgent);
      DISPATCH(ReadMemory);
      DISPATCH(ReadRegisters);
      DISPATCH(WriteRegisters);
      DISPATCH(RemoveBreakpoint);
      DISPATCH(Resume);
      DISPATCH(Status);
      DISPATCH(SysInfo);
      DISPATCH(ThreadStatus);
      DISPATCH(Threads);
      DISPATCH(WriteMemory);
      DISPATCH(LoadInfoHandleTable);
      DISPATCH(UpdateGlobalSettings);

      // Attach is special (see remote_api.h): forward the raw data instead of
      // a deserialized version.
      case debug_ipc::MsgHeader::Type::kAttach:
        api_->OnAttach(std::move(buffer));
        break;

      // Explicitly no "default" to get warnings about unhandled message types,
      // but need to handle these "not a message" types to avoid this warning.
      case debug_ipc::MsgHeader::Type::kNone:
      case debug_ipc::MsgHeader::Type::kNumMessages:
      case debug_ipc::MsgHeader::Type::kNotifyException:
      case debug_ipc::MsgHeader::Type::kNotifyIO:
      case debug_ipc::MsgHeader::Type::kNotifyModules:
      case debug_ipc::MsgHeader::Type::kNotifyProcessExiting:
      case debug_ipc::MsgHeader::Type::kNotifyProcessStarting:
      case debug_ipc::MsgHeader::Type::kNotifyThreadStarting:
      case debug_ipc::MsgHeader::Type::kNotifyThreadExiting:
        break;  // Avoid warning
    }

#undef DISPATCH
  }
}

}  // namespace debug_agent
