// 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 "garnet/lib/debug_ipc/agent_protocol.h"

#include "garnet/lib/debug_ipc/message_reader.h"
#include "garnet/lib/debug_ipc/message_writer.h"
#include "garnet/lib/debug_ipc/protocol_helpers.h"

namespace debug_ipc {

// Record deserializers --------------------------------------------------------

bool Deserialize(MessageReader* reader, ProcessBreakpointSettings* settings) {
  if (!reader->ReadUint64(&settings->process_koid))
    return false;
  if (!reader->ReadUint64(&settings->thread_koid))
    return false;
  return reader->ReadUint64(&settings->address);
}

bool Deserialize(MessageReader* reader, BreakpointSettings* settings) {
  if (!reader->ReadUint32(&settings->breakpoint_id))
    return false;
  if (!reader->ReadBool(&settings->one_shot))
    return false;

  uint32_t stop;
  if (!reader->ReadUint32(&stop))
    return false;
  settings->stop = static_cast<Stop>(stop);

  uint32_t type;
  if (!reader->ReadUint32(&type))
    return false;
  settings->type = static_cast<BreakpointType>(type);

  return Deserialize(reader, &settings->locations);
}

bool Deserialize(MessageReader* reader, RegisterCategory::Type* type) {
  return reader->ReadUint32(reinterpret_cast<uint32_t*>(type));
}

// Record serializers ----------------------------------------------------------

void Serialize(const ProcessTreeRecord& record, MessageWriter* writer) {
  writer->WriteUint32(static_cast<uint32_t>(record.type));
  writer->WriteUint64(record.koid);
  writer->WriteString(record.name);
  Serialize(record.children, writer);
}

void Serialize(const ThreadRecord& record, MessageWriter* writer) {
  writer->WriteUint64(record.koid);
  writer->WriteString(record.name);
  writer->WriteUint32(static_cast<uint32_t>(record.state));
  writer->WriteUint32(static_cast<uint32_t>(record.blocked_reason));
  writer->WriteUint32(static_cast<uint32_t>(record.stack_amount));
  Serialize(record.frames, writer);
}

void Serialize(const MemoryBlock& block, MessageWriter* writer) {
  writer->WriteUint64(block.address);
  writer->WriteBool(block.valid);
  writer->WriteUint32(block.size);
  if (block.valid && block.size > 0)
    writer->WriteBytes(&block.data[0], block.size);
}

void Serialize(const Module& module, MessageWriter* writer) {
  writer->WriteString(module.name);
  writer->WriteUint64(module.base);
  writer->WriteString(module.build_id);
}

void Serialize(const ElfSymbol& symbol, MessageWriter* writer) {
  writer->WriteString(symbol.name);
  writer->WriteUint64(symbol.value);
}

void Serialize(const RegisterCategory& reg_cat, MessageWriter* writer) {
  writer->WriteUint32(*reinterpret_cast<const uint32_t*>(&reg_cat.type));
  Serialize(reg_cat.registers, writer);
}

void Serialize(const StackFrame& frame, MessageWriter* writer) {
  writer->WriteBytes(&frame, sizeof(StackFrame));
}

void Serialize(const AddressRegion& region, MessageWriter* writer) {
  writer->WriteString(region.name);
  writer->WriteUint64(region.base);
  writer->WriteUint64(region.size);
  writer->WriteUint64(region.depth);
}

void Serialize(const BreakpointStats& stats, MessageWriter* writer) {
  writer->WriteUint32(stats.breakpoint_id);
  writer->WriteUint32(stats.hit_count);
  writer->WriteBool(stats.should_delete);
}

// Hello -----------------------------------------------------------------------

bool ReadRequest(MessageReader* reader, HelloRequest* request,
                 uint32_t* transaction_id) {
  MsgHeader header;
  if (!reader->ReadHeader(&header))
    return false;
  *transaction_id = header.transaction_id;
  return true;
}

void WriteReply(const HelloReply& reply, uint32_t transaction_id,
                MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kHello, transaction_id);
  writer->WriteBytes(&reply, sizeof(HelloReply));
}

// Launch ----------------------------------------------------------------------

bool ReadRequest(MessageReader* reader, LaunchRequest* request,
                 uint32_t* transaction_id) {
  MsgHeader header;
  if (!reader->ReadHeader(&header))
    return false;
  *transaction_id = header.transaction_id;

  return Deserialize(reader, &request->argv);
}

void WriteReply(const LaunchReply& reply, uint32_t transaction_id,
                MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kLaunch, transaction_id);
  writer->WriteUint32(reply.status);
  writer->WriteUint64(reply.process_koid);
  writer->WriteString(reply.process_name);
}

// Kill ----------------------------------------------------------------------

bool ReadRequest(MessageReader* reader, KillRequest* request,
                 uint32_t* transaction_id) {
  MsgHeader header;
  if (!reader->ReadHeader(&header))
    return false;
  *transaction_id = header.transaction_id;
  return reader->ReadUint64(&request->process_koid);
}

void WriteReply(const KillReply& reply, uint32_t transaction_id,
                MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kKill, transaction_id);
  writer->WriteUint32(reply.status);
}

// Attach ----------------------------------------------------------------------

bool ReadRequest(MessageReader* reader, AttachRequest* request,
                 uint32_t* transaction_id) {
  MsgHeader header;
  if (!reader->ReadHeader(&header))
    return false;
  *transaction_id = header.transaction_id;
  uint32_t type;
  if (!reader->ReadUint32(&type))
    return false;
  if (type >= static_cast<uint32_t>(AttachRequest::Type::kLast))
    return false;
  request->type = static_cast<AttachRequest::Type>(type);
  return reader->ReadUint64(&request->koid);
}

void WriteReply(const AttachReply& reply, uint32_t transaction_id,
                MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kAttach, transaction_id);
  writer->WriteUint64(reply.koid);
  writer->WriteUint32(reply.status);
  writer->WriteString(reply.name);
}

// Detach ----------------------------------------------------------------------

bool ReadRequest(MessageReader* reader, DetachRequest* request,
                 uint32_t* transaction_id) {
  MsgHeader header;
  if (!reader->ReadHeader(&header))
    return false;
  *transaction_id = header.transaction_id;
  uint32_t type;
  if (!reader->ReadUint32(&type))
    return false;
  if (type >= static_cast<uint32_t>(DetachRequest::Type::kLast))
    return false;
  request->type = static_cast<DetachRequest::Type>(type);
  return reader->ReadUint64(&request->koid);
}

void WriteReply(const DetachReply& reply, uint32_t transaction_id,
                MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kDetach, transaction_id);
  writer->WriteUint32(reply.status);
}

// Pause -----------------------------------------------------------------------

bool ReadRequest(MessageReader* reader, PauseRequest* request,
                 uint32_t* transaction_id) {
  MsgHeader header;
  if (!reader->ReadHeader(&header))
    return false;
  *transaction_id = header.transaction_id;
  if (!reader->ReadUint64(&request->process_koid))
    return false;
  if (!reader->ReadUint64(&request->thread_koid))
    return false;
  return true;
}

void WriteReply(const PauseReply& reply, uint32_t transaction_id,
                MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kPause, transaction_id);
}

// QuitAgent -------------------------------------------------------------------

bool ReadRequest(MessageReader* reader, QuitAgentRequest* request,
                 uint32_t* transaction_id) {
  MsgHeader header;
  if (!reader->ReadHeader(&header))
    return false;
  *transaction_id = header.transaction_id;
  return true;
}

void WriteReply(const QuitAgentReply& reply, uint32_t transaction_id,
                MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kQuitAgent, transaction_id);
}

// Resume ----------------------------------------------------------------------

bool ReadRequest(MessageReader* reader, ResumeRequest* request,
                 uint32_t* transaction_id) {
  MsgHeader header;
  if (!reader->ReadHeader(&header))
    return false;
  *transaction_id = header.transaction_id;
  if (!reader->ReadUint64(&request->process_koid))
    return false;
  if (!Deserialize(reader, &request->thread_koids))
    return false;

  uint32_t how;
  if (!reader->ReadUint32(&how))
    return false;
  if (how >= static_cast<uint32_t>(ResumeRequest::How::kLast))
    return false;
  request->how = static_cast<ResumeRequest::How>(how);

  if (!reader->ReadUint64(&request->range_begin))
    return false;
  if (!reader->ReadUint64(&request->range_end))
    return false;

  return true;
}

void WriteReply(const ResumeReply& reply, uint32_t transaction_id,
                MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kResume, transaction_id);
}

// ProcessTree -----------------------------------------------------------------

bool ReadRequest(MessageReader* reader, ProcessTreeRequest* request,
                 uint32_t* transaction_id) {
  MsgHeader header;
  if (!reader->ReadHeader(&header))
    return false;
  *transaction_id = header.transaction_id;
  return reader->ReadBytes(sizeof(ProcessTreeRequest), request);
}

void WriteReply(const ProcessTreeReply& reply, uint32_t transaction_id,
                MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kProcessTree, transaction_id);
  Serialize(reply.root, writer);
}

// Threads ---------------------------------------------------------------------

bool ReadRequest(MessageReader* reader, ThreadsRequest* request,
                 uint32_t* transaction_id) {
  MsgHeader header;
  if (!reader->ReadHeader(&header))
    return false;
  *transaction_id = header.transaction_id;
  return reader->ReadBytes(sizeof(ThreadsRequest), request);
}

void WriteReply(const ThreadsReply& reply, uint32_t transaction_id,
                MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kThreads, transaction_id);
  Serialize(reply.threads, writer);
}

// ReadMemory ------------------------------------------------------------------

bool ReadRequest(MessageReader* reader, ReadMemoryRequest* request,
                 uint32_t* transaction_id) {
  MsgHeader header;
  if (!reader->ReadHeader(&header))
    return false;
  *transaction_id = header.transaction_id;
  return reader->ReadBytes(sizeof(ReadMemoryRequest), request);
}

void WriteReply(const ReadMemoryReply& reply, uint32_t transaction_id,
                MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kReadMemory, transaction_id);
  Serialize(reply.blocks, writer);
}

// AddOrChangeBreakpoint -------------------------------------------------------

bool ReadRequest(MessageReader* reader, AddOrChangeBreakpointRequest* request,
                 uint32_t* transaction_id) {
  MsgHeader header;
  if (!reader->ReadHeader(&header))
    return false;
  *transaction_id = header.transaction_id;
  return Deserialize(reader, &request->breakpoint);
}

void WriteReply(const AddOrChangeBreakpointReply& reply,
                uint32_t transaction_id, MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kAddOrChangeBreakpoint, transaction_id);
  writer->WriteUint32(reply.status);
}

// RemoveBreakpoint ------------------------------------------------------------

bool ReadRequest(MessageReader* reader, RemoveBreakpointRequest* request,
                 uint32_t* transaction_id) {
  MsgHeader header;
  if (!reader->ReadHeader(&header))
    return false;
  *transaction_id = header.transaction_id;
  return reader->ReadBytes(sizeof(RemoveBreakpointRequest), request);
}

void WriteReply(const RemoveBreakpointReply& reply, uint32_t transaction_id,
                MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kRemoveBreakpoint, transaction_id);
}

// ThreadStatus ----------------------------------------------------------------

bool ReadRequest(MessageReader* reader, ThreadStatusRequest* request,
                 uint32_t* transaction_id) {
  MsgHeader header;
  if (!reader->ReadHeader(&header))
    return false;
  *transaction_id = header.transaction_id;
  return reader->ReadBytes(sizeof(ThreadStatusRequest), request);
}

void WriteReply(const ThreadStatusReply& reply, uint32_t transaction_id,
                MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kThreadStatus, transaction_id);
  Serialize(reply.record, writer);
}

// Modules ---------------------------------------------------------------------

bool ReadRequest(MessageReader* reader, ModulesRequest* request,
                 uint32_t* transaction_id) {
  MsgHeader header;
  if (!reader->ReadHeader(&header))
    return false;
  *transaction_id = header.transaction_id;
  return reader->ReadBytes(sizeof(ModulesRequest), request);
}

void WriteReply(const ModulesReply& reply, uint32_t transaction_id,
                MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kModules, transaction_id);
  Serialize(reply.modules, writer);
}

// Modules ---------------------------------------------------------------------

bool ReadRequest(MessageReader* reader, SymbolTablesRequest* request,
                 uint32_t* transaction_id) {
  MsgHeader header;
  if (!reader->ReadHeader(&header))
    return false;
  *transaction_id = header.transaction_id;
  return reader->ReadBytes(sizeof(SymbolTablesRequest), request);
}

void WriteReply(const SymbolTablesReply& reply, uint32_t transaction_id,
                MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kSymbolTables, transaction_id);
  Serialize(reply.symbols, writer);
}

// JobFilter ------------------------------------------------------------------

bool ReadRequest(MessageReader* reader, JobFilterRequest* request,
                 uint32_t* transaction_id) {
  MsgHeader header;
  if (!reader->ReadHeader(&header))
    return false;
  *transaction_id = header.transaction_id;
  if (!reader->ReadUint64(&request->job_koid))
    return false;
  return Deserialize(reader, &request->filters);
}

void WriteReply(const JobFilterReply& reply, uint32_t transaction_id,
                MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kJobFilter, transaction_id);
  writer->WriteUint32(reply.status);
}

// WriteMemory -----------------------------------------------------------------

bool ReadRequest(MessageReader* reader, WriteMemoryRequest* request,
                 uint32_t* transaction_id) {
  MsgHeader header;
  if (!reader->ReadHeader(&header))
    return false;
  *transaction_id = header.transaction_id;
  if (!reader->ReadUint64(&request->process_koid))
    return false;
  if (!reader->ReadUint64(&request->address))
    return false;
  return Deserialize(reader, &request->data);
}

void WriteReply(const WriteMemoryReply& reply, uint32_t transaction_id,
                MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kWriteMemory, transaction_id);
  writer->WriteUint64(reply.status);
}

// ReadRegisters ---------------------------------------------------------------

bool ReadRequest(MessageReader* reader, ReadRegistersRequest* request,
                 uint32_t* transaction_id) {
  MsgHeader header;
  if (!reader->ReadHeader(&header))
    return false;
  *transaction_id = header.transaction_id;

  if (!reader->ReadUint64(&request->process_koid) ||
      !reader->ReadUint64(&request->thread_koid))
    return false;

  return Deserialize(reader, &request->categories);
}

void WriteReply(const ReadRegistersReply& reply, uint32_t transaction_id,
                MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kReadRegisters, transaction_id);
  Serialize(reply.categories, writer);
}

// WriteRegisters --------------------------------------------------------------

bool ReadRequest(MessageReader* reader, WriteRegistersRequest* request,
                 uint32_t* transaction_id) {
  MsgHeader header;
  if (!reader->ReadHeader(&header))
    return false;
  *transaction_id = header.transaction_id;

  if (!reader->ReadUint64(&request->process_koid) ||
      !reader->ReadUint64(&request->thread_koid))
    return false;
  return Deserialize(reader, &request->registers);
}

void WriteReply(const WriteRegistersReply& reply, uint32_t transaction_id,
                MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kWriteRegisters, transaction_id);
  writer->WriteUint64(reply.status);
}

// Address space ---------------------------------------------------------------

bool ReadRequest(MessageReader* reader, AddressSpaceRequest* request,
                 uint32_t* transaction_id) {
  MsgHeader header;
  if (!reader->ReadHeader(&header))
    return false;
  *transaction_id = header.transaction_id;
  return reader->ReadBytes(sizeof(AddressSpaceRequest), request);
}

void WriteReply(const AddressSpaceReply& reply, uint32_t transaction_id,
                MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kAddressSpace, transaction_id);
  Serialize(reply.map, writer);
}

// Notifications ---------------------------------------------------------------

void WriteNotifyProcess(const NotifyProcess& notify, MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kNotifyProcessExiting, 0);
  writer->WriteUint64(notify.process_koid);
  writer->WriteInt64(notify.return_code);
}

void WriteNotifyProcessStarting(const NotifyProcessStarting& notify,
                                MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kNotifyProcessStarting, 0);
  writer->WriteUint64(notify.koid);
  writer->WriteString(notify.name);
}

void WriteNotifyThread(MsgHeader::Type type, const NotifyThread& notify,
                       MessageWriter* writer) {
  writer->WriteHeader(type, 0);
  writer->WriteUint64(notify.process_koid);
  Serialize(notify.record, writer);
}

void WriteNotifyException(const NotifyException& notify,
                          MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kNotifyException, 0);
  writer->WriteUint64(notify.process_koid);
  Serialize(notify.thread, writer);
  writer->WriteUint32(static_cast<uint32_t>(notify.type));
  Serialize(notify.hit_breakpoints, writer);
}

void WriteNotifyModules(const NotifyModules& notify, MessageWriter* writer) {
  writer->WriteHeader(MsgHeader::Type::kNotifyModules, 0);
  writer->WriteUint64(notify.process_koid);
  Serialize(notify.modules, writer);
  Serialize(notify.stopped_thread_koids, writer);
}

}  // namespace debug_ipc
