// 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)) {
    FX_LOGS(ERROR) << "Got bad debugger " << type_string << "Request, ignoring.";
    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) {
      FX_LOGS(ERROR) << "Invalid message type " << static_cast<uint32_t>(header.type)
                     << ", ignoring.";
      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
