// 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/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_ipc::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[0], 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(Hello);
      DISPATCH(Launch);
      DISPATCH(Kill);
      DISPATCH(Pause);
      DISPATCH(QuitAgent);
      DISPATCH(ProcessTree);
      DISPATCH(Threads);
      DISPATCH(Modules);
      DISPATCH(ReadMemory);
      DISPATCH(ReadRegisters);
      DISPATCH(WriteRegisters);
      DISPATCH(Resume);
      DISPATCH(Detach);
      DISPATCH(AddOrChangeBreakpoint);
      DISPATCH(RemoveBreakpoint);
      DISPATCH(ThreadStatus);
      DISPATCH(AddressSpace);
      DISPATCH(JobFilter);
      DISPATCH(WriteMemory);

      // 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::kNotifyProcessExiting:
      case debug_ipc::MsgHeader::Type::kNotifyProcessStarting:
      case debug_ipc::MsgHeader::Type::kNotifyThreadStarting:
      case debug_ipc::MsgHeader::Type::kNotifyThreadExiting:
      case debug_ipc::MsgHeader::Type::kNotifyException:
      case debug_ipc::MsgHeader::Type::kNotifyModules:
        break;  // Avoid warning
    }

#undef DISPATCH
  }
}

}  // namespace debug_agent
