// Copyright 2016 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 "cmd_handler.h"

#include <algorithm>
#include <cinttypes>
#include <string>

#include "garnet/lib/debugger_utils/util.h"

#include "garnet/lib/inferior_control/registers.h"
#include "garnet/lib/inferior_control/thread.h"

#include "lib/fxl/logging.h"
#include "lib/fxl/strings/split_string.h"
#include "lib/fxl/strings/string_number_conversions.h"
#include "lib/fxl/strings/string_printf.h"

#include "server.h"
#include "thread_action_list.h"
#include "util.h"

namespace debugserver {

namespace {

const char kSupportedFeatures[] =
    "QNonStop+;"
#if 0  // TODO(dje)
  "QThreadEvents+;"
#endif
#if 0  // TODO(dje)
  "swbreak+;"
#endif
    "qXfer:auxv:read+";

const char kAttached[] = "Attached";
const char kCurrentThreadId[] = "C";
const char kFirstThreadInfo[] = "fThreadInfo";
const char kNonStop[] = "NonStop";
const char kRcmd[] = "Rcmd,";
const char kSubsequentThreadInfo[] = "sThreadInfo";
const char kSupported[] = "Supported";
const char kXfer[] = "Xfer";

// v Commands
const char kAttach[] = "Attach;";
const char kCont[] = "Cont;";
const char kKill[] = "Kill;";
const char kRun[] = "Run;";

// qRcmd commands
const char kExit[] = "exit";
const char kHelp[] = "help";
const char kQuit[] = "quit";
const char kSet[] = "set";
const char kShow[] = "show";

// This always returns true so that command handlers can simple call "return
// ReplyOK()" rather than "ReplyOK(); return true;
bool ReplyOK(CommandHandler::ResponseCallback callback) {
  callback("OK");
  return true;
}

// This always returns true so that command handlers can simple call "return
// ReplyWithError()" rather than "ReplyWithError(); return true;
bool ReplyWithError(ErrorCode error_code,
                    CommandHandler::ResponseCallback callback) {
  std::string error_rsp = BuildErrorPacket(error_code);
  callback(error_rsp);
  return true;
}

// Returns true if |str| starts with |prefix|.
bool StartsWith(const fxl::StringView& str, const fxl::StringView& prefix) {
  return str.substr(0, prefix.size()) == prefix;
}

std::vector<std::string> BuildArgvFor_vRun(const fxl::StringView& packet) {
  std::vector<std::string> argv;
  size_t len = packet.size();
  size_t s = 0;

  while (s < len) {
    size_t semi = packet.find(';', s);
    size_t n;
    if (semi == fxl::StringView::npos)
      n = len - s;
    else
      n = semi - s;
    std::vector<uint8_t> arg =
        debugger_utils::DecodeByteArrayString(packet.substr(s, n));
    auto char_arg = reinterpret_cast<char*>(arg.data());
    argv.push_back(std::string(char_arg, arg.size()));
    if (semi == fxl::StringView::npos)
      s = len;
    else
      s = semi + 1;
  }

  return argv;
}

}  // namespace

CommandHandler::CommandHandler(RspServer* server)
    : server_(server), in_thread_info_sequence_(false) {
  FXL_DCHECK(server_);
}

bool CommandHandler::HandleCommand(const fxl::StringView& packet,
                                   ResponseCallback callback) {
  // GDB packets are prefixed with a letter that maps to a particular command
  // "family". We do the initial multiplexing here and let each individual
  // sub-handler deal with the rest.
  if (packet.empty()) {
    // TODO(armansito): Is there anything meaningful that we can do here?
    FXL_LOG(ERROR) << "Empty packet received";
    return false;
  }

  switch (packet[0]) {
    case '?':  // Indicate the reason the target halted
      if (packet.size() > 1)
        break;
      return HandleQuestionMark(std::move(callback));
    case 'c':  // Continue (at addr)
      return Handle_c(packet.substr(1), std::move(callback));
    case 'C':  // Continue with signal (optionally at addr)
      return Handle_C(packet.substr(1), std::move(callback));
    case 'D':  // Detach
      return Handle_D(packet.substr(1), std::move(callback));
    case 'g':  // Read general registers
      if (packet.size() > 1)
        break;
      return Handle_g(std::move(callback));
    case 'G':  // Write general registers
      return Handle_G(packet.substr(1), std::move(callback));
    case 'H':  // Set a thread for subsequent operations
      return Handle_H(packet.substr(1), std::move(callback));
    case 'm':  // Read memory
      return Handle_m(packet.substr(1), std::move(callback));
    case 'M':  // Write memory
      return Handle_M(packet.substr(1), std::move(callback));
    case 'q':  // General query packet
    case 'Q':  // General set packet
    {
      fxl::StringView prefix, params;
      ExtractParameters(packet.substr(1), &prefix, &params);

      FXL_VLOG(1) << "\'" << packet[0] << "\' packet - prefix: " << prefix
                  << ", params: " << params;

      if (packet[0] == 'q')
        return Handle_q(prefix, params, std::move(callback));
      return Handle_Q(prefix, params, std::move(callback));
    }
    case 'T':  // Is thread alive?
      return Handle_T(packet.substr(1), std::move(callback));
    case 'v':  // v-packets
      return Handle_v(packet.substr(1), std::move(callback));
    case 'z':  // Remove software breakpoint
    case 'Z':  // Insert software breakpoint
      return Handle_zZ(packet[0] == 'Z', packet.substr(1), std::move(callback));
    default:
      break;
  }

  return false;
}

bool CommandHandler::HandleQuestionMark(ResponseCallback callback) {
  // TODO(armansito): Implement this once we actually listen to thread/process
  // exceptions. The logic for NonStop mode is fairly simple:
  //    1. Tell Server to drop any pending and/or queued Stop Reply
  //    notifications.
  //
  //    2. Go through all processes and send a notification for the status of
  //    each.
  //
  //    3. If there is no inferior or the current inferior is not started, then
  //    reply "OK".
  return ReplyOK(std::move(callback));
}

bool CommandHandler::Handle_c(const fxl::StringView& packet,
                              ResponseCallback callback) {
  // If there is no current process or if the current process isn't attached,
  // then report an error.
  inferior_control::Process* current_process = server_->current_process();
  if (!current_process || !current_process->IsAttached()) {
    FXL_LOG(ERROR) << "c: No inferior";
    return ReplyWithError(ErrorCode::PERM, std::move(callback));
  }

  inferior_control::Thread* current_thread = server_->current_thread();

  // If the packet contains an address parameter, then try to set the program
  // counter to then continue at that address. Otherwise, the PC register will
  // remain untouched.
  zx_vaddr_t addr;
  if (!packet.empty()) {
    if (!fxl::StringToNumberWithError<zx_vaddr_t>(packet, &addr,
                                                  fxl::Base::k16)) {
      FXL_LOG(ERROR) << "c: Malformed address given: " << packet;
      return ReplyWithError(ErrorCode::INVAL, std::move(callback));
    }

    // If there is no current thread, then report error. This is a special case
    // that means that the process hasn't started yet.
    if (!current_thread) {
      FXL_DCHECK(!current_process->IsLive());
      return ReplyWithError(ErrorCode::PERM, std::move(callback));
    }

    if (!current_thread->registers()->RefreshGeneralRegisters()) {
      return ReplyWithError(ErrorCode::PERM, std::move(callback));
    }
    if (!current_thread->registers()->SetRegister(
            inferior_control::GetPCRegisterNumber(), &addr, sizeof(addr))) {
      return ReplyWithError(ErrorCode::PERM, std::move(callback));
    }
    if (!current_thread->registers()->WriteGeneralRegisters()) {
      return ReplyWithError(ErrorCode::PERM, std::move(callback));
    }

    // TODO(armansito): Restore the PC register to its original state in case of
    // a failure condition below?
  }

  // If there is a current thread, then tell it to continue.
  if (current_thread) {
    if (!current_thread->Resume())
      return ReplyWithError(ErrorCode::PERM, std::move(callback));

    return ReplyOK(std::move(callback));
  }

  // There is no current thread. This means that the process hasn't been started
  // yet. We start it and set the current thread to the first one the kernel
  // gives us.
  // TODO(armansito): Remove this logic now that we handle
  // ZX_EXCP_THREAD_STARTING?
  FXL_DCHECK(!current_process->IsLive());
  if (!current_process->Start()) {
    FXL_LOG(ERROR) << "c: Failed to start the current inferior";
    return ReplyWithError(ErrorCode::PERM, std::move(callback));
  }

  // Try to set the current thread.
  // TODO(armansito): Can this be racy?
  current_thread = current_process->PickOneThread();
  if (current_thread)
    server_->SetCurrentThread(current_thread);

  return ReplyOK(std::move(callback));
}

bool CommandHandler::Handle_C(const fxl::StringView& packet,
                              ResponseCallback callback) {
  // If there is no current process or if the current process isn't attached,
  // then report an error.
  inferior_control::Process* current_process = server_->current_process();
  if (!current_process || !current_process->IsAttached()) {
    FXL_LOG(ERROR) << "C: No inferior";
    return ReplyWithError(ErrorCode::PERM, std::move(callback));
  }

  inferior_control::Thread* current_thread = server_->current_thread();
  if (!current_thread) {
    FXL_LOG(ERROR) << "C: No current thread";
    return ReplyWithError(ErrorCode::PERM, std::move(callback));
  }

  // Parse the parameters. The packet format is: sig[;addr]
  size_t semicolon = packet.find(';');
  if (semicolon == fxl::StringView::npos)
    semicolon = packet.size();

  int signo;
  if (!fxl::StringToNumberWithError<int>(packet.substr(0, semicolon), &signo,
                                         fxl::Base::k16)) {
    FXL_LOG(ERROR) << "C: Malformed packet: " << packet;
    return ReplyWithError(ErrorCode::INVAL, std::move(callback));
  }

  inferior_control::GdbSignal thread_signo = current_thread->GetGdbSignal();
  // TODO(dje): kNone may be a better value to use here.
  if (thread_signo == inferior_control::GdbSignal::kUnsupported) {
    FXL_LOG(ERROR) << "C: Current thread has received no signal";
    return ReplyWithError(ErrorCode::PERM, std::move(callback));
  }
  int int_thread_signo = static_cast<int>(thread_signo);

  if (int_thread_signo != signo) {
    FXL_LOG(ERROR) << "C: Signal numbers don't match - actual: "
                   << int_thread_signo << ", received: " << signo;
    return ReplyWithError(ErrorCode::PERM, std::move(callback));
  }

  auto addr_param = packet.substr(semicolon);

  // If the packet contains an address parameter, then try to set the program
  // counter to then continue at that address. Otherwise, the PC register will
  // remain untouched.
  // TODO(armansito): Make Thread::Resume take an optional address argument so
  // we don't have to keep repeating this code.
  if (!addr_param.empty()) {
    zx_vaddr_t addr;
    if (!fxl::StringToNumberWithError<zx_vaddr_t>(addr_param, &addr,
                                                  fxl::Base::k16)) {
      FXL_LOG(ERROR) << "C: Malformed address given: " << packet;
      return ReplyWithError(ErrorCode::INVAL, std::move(callback));
    }

    if (!current_thread->registers()->RefreshGeneralRegisters()) {
      return ReplyWithError(ErrorCode::PERM, std::move(callback));
    }
    if (!current_thread->registers()->SetRegister(
            inferior_control::GetPCRegisterNumber(), &addr, sizeof(addr))) {
      return ReplyWithError(ErrorCode::PERM, std::move(callback));
    }
    if (!current_thread->registers()->WriteGeneralRegisters()) {
      return ReplyWithError(ErrorCode::PERM, std::move(callback));
    }

    // TODO(armansito): Restore the PC register to its original state in case of
    // a failure condition below?
  }

  if (!current_thread->Resume()) {
    FXL_LOG(ERROR) << "Failed to resume thread";
    return ReplyWithError(ErrorCode::PERM, std::move(callback));
  }

  return ReplyOK(std::move(callback));
}

bool CommandHandler::Handle_D(const fxl::StringView& packet,
                              ResponseCallback callback) {
  // If there is no current process or if the current process isn't attached,
  // then report an error.
  inferior_control::Process* current_process = server_->current_process();
  if (!current_process) {
    FXL_LOG(ERROR) << "D: No inferior";
    return ReplyWithError(ErrorCode::PERM, std::move(callback));
  }

  // For now we only support detaching from the one process we have.
  if (packet[0] == ';') {
    zx_koid_t pid;
    if (!fxl::StringToNumberWithError<zx_koid_t>(packet.substr(1), &pid,
                                                 fxl::Base::k16)) {
      FXL_LOG(ERROR) << "D: bad pid: " << packet;
      return ReplyWithError(ErrorCode::INVAL, std::move(callback));
    }
    if (pid != current_process->id()) {
      FXL_LOG(ERROR) << "D: unknown pid: " << pid;
      return ReplyWithError(ErrorCode::INVAL, std::move(callback));
    }
  } else if (packet != "") {
    FXL_LOG(ERROR) << "D: Malformed packet: " << packet;
    return ReplyWithError(ErrorCode::INVAL, std::move(callback));
  }

  if (!current_process->IsAttached()) {
    FXL_LOG(ERROR) << "D: Not attached to process " << current_process->id();
    return ReplyWithError(ErrorCode::NOENT, std::move(callback));
  }

  if (!current_process->Detach()) {
    // At the moment this shouldn't happen, but we don't want to kill the
    // debug session because of it. The details of the failure are already
    // logged by Detach().
    return ReplyWithError(ErrorCode::PERM, std::move(callback));
  }
  return ReplyOK(std::move(callback));
}

bool CommandHandler::Handle_g(ResponseCallback callback) {
  // If there is no current process or if the current process isn't attached,
  // then report an error.
  inferior_control::Process* current_process = server_->current_process();
  if (!current_process || !current_process->IsAttached()) {
    FXL_LOG(ERROR) << "g: No inferior";
    return ReplyWithError(ErrorCode::NOENT, std::move(callback));
  }

  // If there is no current thread, then we reply with "0"s for all registers.
  // TODO(armansito): gG packets are technically used to read/write "ALL"
  // registers, not just the general registers. We'll have to take this into
  // account in the future, though for now we're just supporting general
  // registers.
  std::string result;
  if (!server_->current_thread()) {
    result =
        inferior_control::Registers::GetUninitializedGeneralRegistersAsString();
  } else {
    inferior_control::Registers* regs = server_->current_thread()->registers();
    FXL_DCHECK(regs);
    result = regs->GetGeneralRegistersAsString();
  }

  if (result.empty()) {
    FXL_LOG(ERROR) << "g: Failed to read register values";
    return ReplyWithError(ErrorCode::PERM, std::move(callback));
  }

  callback(result);
  return true;
}

bool CommandHandler::Handle_G(const fxl::StringView& packet,
                              ResponseCallback callback) {
  // If there is no current process or if the current process isn't attached,
  // then report an error.
  inferior_control::Process* current_process = server_->current_process();
  if (!current_process || !current_process->IsAttached()) {
    FXL_LOG(ERROR) << "G: No inferior";
    return ReplyWithError(ErrorCode::NOENT, std::move(callback));
  }

  // If there is no current thread report an error.
  inferior_control::Thread* current_thread = server_->current_thread();
  if (!current_thread) {
    FXL_LOG(ERROR) << "G: No current thread";
    return ReplyWithError(ErrorCode::NOENT, std::move(callback));
  }

  // We pass the packet here directly since Registers handles the parsing.
  // TODO(armansito): gG packets are technically used to read/write "ALL"
  // registers, not just the general registers. We'll have to take this into
  // account in the future, though for now we're just supporting general
  // registers.
  if (!current_thread->registers()->SetGeneralRegistersFromString(packet)) {
    FXL_LOG(ERROR) << "G: Failed to write to general registers";
    return ReplyWithError(ErrorCode::PERM, std::move(callback));
  }
  if (!current_thread->registers()->WriteGeneralRegisters()) {
    return ReplyWithError(ErrorCode::PERM, std::move(callback));
  }

  return ReplyOK(std::move(callback));
}

bool CommandHandler::Handle_H(const fxl::StringView& packet,
                              ResponseCallback callback) {
  // Here we set the "current thread" for subsequent operations
  // (‘m’, ‘M’, ‘g’, ‘G’, et.al.).
  // There are two types of an H packet. 'c' and 'g'. We claim to not support
  // 'c' because it's specified as deprecated.

  // Packet should at least contain 'c' or 'g' and some characters for the
  // thread id.
  if (packet.size() < 2)
    return ReplyWithError(ErrorCode::INVAL, std::move(callback));

  switch (packet[0]) {
    case 'c':  // fall through
    case 'g': {
      int64_t pid, tid;
      bool has_pid;
      if (!ParseThreadId(packet.substr(1), &has_pid, &pid, &tid))
        return ReplyWithError(ErrorCode::INVAL, std::move(callback));

      // We currently support debugging only one process.
      // TODO(armansito): What to do with a process ID? Replying with an empty
      // packet for now.
      if (has_pid) {
        FXL_LOG(WARNING)
            << "Specifying a pid while setting the current thread is"
            << " not supported";
        return false;
      }

      // Setting the current thread to "all threads" doesn't make much sense.
      if (tid < 0) {
        FXL_LOG(ERROR) << "Cannot set the current thread to all threads";
        return ReplyWithError(ErrorCode::INVAL, std::move(callback));
      }

      inferior_control::Process* current_process = server_->current_process();

      // Note that at this point we may have a process but are not necessarily
      // attached yet. GDB sends the Hg0 packet early on, and expects it to
      // succeed.
      if (!current_process) {
        FXL_LOG(ERROR) << "No inferior exists";

        // If we're given a positive thread ID but there is currently no
        // inferior, then report error?
        if (!tid) {
          FXL_LOG(ERROR) << "Cannot set a current thread with no inferior";
          return ReplyWithError(ErrorCode::PERM, std::move(callback));
        }

        FXL_LOG(WARNING) << "Setting current thread to NULL for tid=0";

        server_->SetCurrentThread(nullptr);
        return ReplyOK(std::move(callback));
      }

      // If the process hasn't started yet it will have no threads. Since "Hg0"
      // is one of the first things that GDB sends after a connection (and
      // since we don't run the process right away), we lie to GDB and set the
      // current thread to null.
      if (!current_process->IsLive()) {
        FXL_LOG(INFO) << "Current process has no threads yet but we pretend to "
                      << "set one";
        server_->SetCurrentThread(nullptr);
        return ReplyOK(std::move(callback));
      }

      current_process->EnsureThreadMapFresh();

      inferior_control::Thread* thread;

      // A thread ID value of 0 means "pick an arbitrary thread".
      if (tid == 0)
        thread = current_process->PickOneThread();
      else
        thread = current_process->FindThreadById(tid);

      if (!thread) {
        FXL_LOG(ERROR) << "Failed to set the current thread";
        return ReplyWithError(ErrorCode::PERM, std::move(callback));
      }

      server_->SetCurrentThread(thread);
      return ReplyOK(std::move(callback));
    }
    default:
      break;
  }

  return false;
}

bool CommandHandler::Handle_m(const fxl::StringView& packet,
                              ResponseCallback callback) {
  // If there is no current process or if the current process isn't attached,
  // then report an error.
  inferior_control::Process* current_process = server_->current_process();
  if (!current_process || !current_process->IsAttached()) {
    FXL_LOG(ERROR) << "m: No inferior";
    return ReplyWithError(ErrorCode::NOENT, std::move(callback));
  }

  // The "m" packet should have two arguments for addr and length, separated by
  // a single comma.
  auto params = fxl::SplitString(packet, ",", fxl::kKeepWhitespace,
                                 fxl::kSplitWantNonEmpty);
  if (params.size() != 2) {
    FXL_LOG(ERROR) << "m: Malformed packet: " << packet;
    return ReplyWithError(ErrorCode::INVAL, std::move(callback));
  }

  uintptr_t addr;
  size_t length;
  if (!fxl::StringToNumberWithError<uintptr_t>(params[0], &addr,
                                               fxl::Base::k16) ||
      !fxl::StringToNumberWithError<size_t>(params[1], &length,
                                            fxl::Base::k16)) {
    FXL_LOG(ERROR) << "m: Malformed params: " << packet;
    return ReplyWithError(ErrorCode::NOENT, std::move(callback));
  }

  std::unique_ptr<uint8_t[]> buffer(new uint8_t[length]);
  if (!current_process->ReadMemory(addr, buffer.get(), length)) {
    FXL_LOG(ERROR) << "m: Failed to read memory";
    return ReplyWithError(ErrorCode::PERM, std::move(callback));
  }

  std::string result =
      debugger_utils::EncodeByteArrayString(buffer.get(), length);
  callback(result);
  return true;
}

bool CommandHandler::Handle_M(const fxl::StringView& packet,
                              ResponseCallback callback) {
  // If there is no current process or if the current process isn't attached,
  // then report an error.
  inferior_control::Process* current_process = server_->current_process();
  if (!current_process || !current_process->IsAttached()) {
    FXL_LOG(ERROR) << "M: No inferior";
    return ReplyWithError(ErrorCode::NOENT, std::move(callback));
  }

  // The "M" packet parameters look like this: "addr,length:XX...".
  // First, extract the addr,len and data sections. Using fxl::kSplitWantAll
  // here since the data portion could technically be empty if the given length
  // is 0.
  auto params =
      fxl::SplitString(packet, ":", fxl::kKeepWhitespace, fxl::kSplitWantAll);
  if (params.size() != 2) {
    FXL_LOG(ERROR) << "M: Malformed packet: " << packet;
    return ReplyWithError(ErrorCode::INVAL, std::move(callback));
  }

  fxl::StringView data = params[1];

  // Extract addr and len
  params = fxl::SplitString(params[0], ",", fxl::kKeepWhitespace,
                            fxl::kSplitWantNonEmpty);
  if (params.size() != 2) {
    FXL_LOG(ERROR) << "M: Malformed packet: " << packet;
    return ReplyWithError(ErrorCode::INVAL, std::move(callback));
  }

  uintptr_t addr;
  size_t length;
  if (!fxl::StringToNumberWithError<uintptr_t>(params[0], &addr,
                                               fxl::Base::k16) ||
      !fxl::StringToNumberWithError<size_t>(params[1], &length,
                                            fxl::Base::k16)) {
    FXL_LOG(ERROR) << "M: Malformed params: " << packet;
    return ReplyWithError(ErrorCode::INVAL, std::move(callback));
  }

  FXL_VLOG(1) << fxl::StringPrintf("M: addr=0x%" PRIxPTR ", len=%lu", addr,
                                   length);

  auto data_bytes = debugger_utils::DecodeByteArrayString(data);
  if (data_bytes.size() != length) {
    FXL_LOG(ERROR) << "M: payload length doesn't match length argument - "
                   << "payload size: " << data_bytes.size()
                   << ", length requested: " << length;
    return ReplyWithError(ErrorCode::INVAL, std::move(callback));
  }

  // Short-circuit if |length| is 0.
  if (length &&
      !current_process->WriteMemory(addr, data_bytes.data(), length)) {
    FXL_LOG(ERROR) << "M: Failed to write memory";

    // TODO(armansito): The error code definitions from GDB aren't really
    // granular enough to aid debug various error conditions (e.g. we may want
    // to report why the memory write failed based on the zx_status_t returned
    // from Zircon). (See TODO in util.h).
    return ReplyWithError(ErrorCode::PERM, std::move(callback));
  }

  return ReplyOK(std::move(callback));
}

bool CommandHandler::Handle_q(const fxl::StringView& prefix,
                              const fxl::StringView& params,
                              ResponseCallback callback) {
  if (prefix == kAttached)
    return HandleQueryAttached(params, std::move(callback));

  if (prefix == kCurrentThreadId)
    return HandleQueryCurrentThreadId(params, std::move(callback));

  if (prefix == kFirstThreadInfo)
    return HandleQueryThreadInfo(true, std::move(callback));

  // The qRcmd packet is different than most. It uses , as a delimiter, not :.
  if (StartsWith(prefix, kRcmd))
    return HandleQueryRcmd(prefix.substr(std::strlen(kRcmd)),
                           std::move(callback));

  if (prefix == kSubsequentThreadInfo)
    return HandleQueryThreadInfo(false, std::move(callback));

  if (prefix == kSupported)
    return HandleQuerySupported(params, std::move(callback));

  if (prefix == kXfer)
    return HandleQueryXfer(params, std::move(callback));

  // TODO(dje): TO-195
  // - QDisableRandomization:VALUE ?
  // - qGetTLSAddr:THREAD-ID,OFFSET,LM
  // - qThreadExtraInfo,THREAD-ID ?

  return false;
}

bool CommandHandler::Handle_Q(const fxl::StringView& prefix,
                              const fxl::StringView& params,
                              ResponseCallback callback) {
  if (prefix == kNonStop)
    return HandleSetNonStop(params, std::move(callback));

  return false;
}

bool CommandHandler::Handle_T(const fxl::StringView& packet,
                              ResponseCallback callback) {
  // If there is no current process or if the current process isn't attached,
  // then report an error.
  inferior_control::Process* current_process = server_->current_process();
  if (!current_process || !current_process->IsAttached()) {
    FXL_LOG(ERROR) << "T: No inferior";
    return ReplyWithError(ErrorCode::NOENT, std::move(callback));
  }

  zx_koid_t tid;
  if (!fxl::StringToNumberWithError<zx_koid_t>(packet, &tid, fxl::Base::k16)) {
    FXL_LOG(ERROR) << "T: Malformed thread id given: " << packet;
    return ReplyWithError(ErrorCode::INVAL, std::move(callback));
  }

  inferior_control::Thread* thread = current_process->FindThreadById(tid);
  if (!thread) {
    FXL_LOG(ERROR) << "T: no such thread: " << packet;
    return ReplyWithError(ErrorCode::NOENT, std::move(callback));
  }
  if (!thread->IsLive()) {
    FXL_LOG(ERROR) << "T: thread found, but not live: " << packet;
    return ReplyWithError(ErrorCode::NOENT, std::move(callback));
  }

  return ReplyOK(std::move(callback));
}

bool CommandHandler::Handle_v(const fxl::StringView& packet,
                              ResponseCallback callback) {
  if (StartsWith(packet, kAttach))
    return Handle_vAttach(packet.substr(std::strlen(kAttach)),
                          std::move(callback));
  if (StartsWith(packet, kCont))
    return Handle_vCont(packet.substr(std::strlen(kCont)), std::move(callback));
  if (StartsWith(packet, kKill))
    return Handle_vKill(packet.substr(std::strlen(kKill)), std::move(callback));
  if (StartsWith(packet, kRun))
    return Handle_vRun(packet.substr(std::strlen(kRun)), std::move(callback));

  return false;
}

bool CommandHandler::Handle_zZ(bool insert, const fxl::StringView& packet,
                               ResponseCallback callback) {
// Z0 needs more work. Disabled until ready.
// One issue is we need to support the swbreak feature.
#if 0
  // A Z packet contains the "type,addr,kind" parameters before all other
  // optional parameters, which follow an optional ';' character. Check to see
  // if there are any optional parameters:
  size_t semicolon = packet.find(';');

  // fxl::StringView::find returns npos if it can't find the character. Adjust
  // |semicolon| to point just beyond the end of |packet| so that
  // packet.substr() works..
  if (semicolon == fxl::StringView::npos)
    semicolon = packet.size();

  auto params = fxl::SplitString(packet.substr(0, semicolon), ",",
                                 fxl::kKeepWhitespace, fxl::kSplitWantNonEmpty);
  if (params.size() != 3) {
    FXL_LOG(ERROR) << "zZ: 3 required parameters missing";
    return ReplyWithError(ErrorCode::INVAL, std::move(callback));
  }

  size_t type;
  uintptr_t addr;
  size_t kind;
  if (!fxl::StringToNumberWithError<uintptr_t>(params[0], &type,
                                               fxl::Base::k16) ||
      !fxl::StringToNumberWithError<uintptr_t>(params[1], &addr,
                                               fxl::Base::k16) ||
      !fxl::StringToNumberWithError<size_t>(params[2], &kind, fxl::Base::k16)) {
    FXL_LOG(ERROR) << "zZ: Failed to parse |type|, |addr| and |kind|";
    return ReplyWithError(ErrorCode::INVAL, std::move(callback));
  }

  auto optional_params = packet.substr(semicolon);

  // "Remove breakpoint" packets don't contain any optional fields.
  if (!insert && !optional_params.empty()) {
    FXL_LOG(ERROR) << "zZ: Malformed packet";
    return ReplyWithError(ErrorCode::INVAL, std::move(callback));
  }

  switch (type) {
    case 0:
      if (insert)
        return InsertSoftwareBreakpoint(addr, kind, optional_params, std::move(callback));
      return RemoveSoftwareBreakpoint(addr, kind, std::move(callback));
    default:
      break;
  }

  FXL_LOG(WARNING) << "Breakpoints of type " << type
                   << " currently not supported";
#endif
  return false;
}

bool CommandHandler::HandleQueryAttached(const fxl::StringView& params,
                                         ResponseCallback callback) {
  // We don't support multiprocessing yet, so make sure we received the version
  // of qAttached that doesn't have a "pid" parameter.
  if (!params.empty())
    return ReplyWithError(ErrorCode::INVAL, std::move(callback));

  // The response is "1" if we attached to an existing process, or "0" if we
  // created a new one. We currently don't support the former, so always send
  // "0".
  callback("0");
  return true;
}

bool CommandHandler::HandleQueryCurrentThreadId(const fxl::StringView& params,
                                                ResponseCallback callback) {
  // The "qC" packet has no parameters.
  if (!params.empty())
    return ReplyWithError(ErrorCode::INVAL, std::move(callback));

  inferior_control::Thread* current_thread = server_->current_thread();
  if (!current_thread) {
    // If there is a current process and it has been started, pick one thread
    // and set that as the current one. This is our work around for lying to GDB
    // about setting a current thread in response to an early Hg0 packet.
    inferior_control::Process* current_process = server_->current_process();
    if (!current_process || !current_process->IsLive()) {
      FXL_LOG(ERROR) << "qC: Current thread has not been set";
      return ReplyWithError(ErrorCode::PERM, std::move(callback));
    }

    FXL_VLOG(1) << "qC: Picking one arbitrary thread";
    current_thread = current_process->PickOneThread();
    if (!current_thread) {
      FXL_VLOG(1) << "qC: Failed to pick a thread";
      return ReplyWithError(ErrorCode::PERM, std::move(callback));
    }
  }

  std::string thread_id =
      fxl::NumberToString<zx_koid_t>(current_thread->id(), fxl::Base::k16);

  std::string reply = "QC" + thread_id;
  callback(reply);
  return true;
}

bool CommandHandler::HandleQueryRcmd(const fxl::StringView& command,
                                     ResponseCallback callback) {
  auto cmd_string = debugger_utils::DecodeString(command);
  std::vector<fxl::StringView> argv = fxl::SplitString(
      cmd_string, " ", fxl::kTrimWhitespace, fxl::kSplitWantNonEmpty);
  if (argv.size() == 0) {
    // No command, just reply OK.
    return ReplyOK(std::move(callback));
  }
  auto cmd = argv[0];

  // We support both because qemu uses "quit" and GNU gdbserver uses "exit".
  if (cmd == kQuit || cmd == kExit) {
    if (argv.size() != 1)
      goto bad_command;
    ReplyOK(std::move(callback));
    server_->PostQuitMessageLoop(true);
  } else if (cmd == kHelp) {
    if (argv.size() != 1)
      goto bad_command;
    static constexpr char kHelpText[] =
        "help - print this help text\n"
        "exit - quit debugserver\n"
        "quit - quit debugserver\n"
        "set <parameter> <value>\n"
        "show <parameter>\n"
        "\n"
        "Parameters:\n"
        "  verbosity - useful range is -2 to 3 (-2 is most verbose)\n";
    callback(debugger_utils::EncodeString(kHelpText));
  } else if (cmd == kSet) {
    if (argv.size() != 3)
      goto bad_command;
    if (!server_->SetParameter(argv[1], argv[2]))
      goto bad_command;
    ReplyOK(std::move(callback));
  } else if (cmd == kShow) {
    if (argv.size() != 2)
      goto bad_command;
    std::string value;
    if (!server_->GetParameter(argv[1], &value))
      goto bad_command;
    callback(debugger_utils::EncodeString("Value is " + value + "\n"));
  } else {
    callback(debugger_utils::EncodeString("Invalid monitor command\n"));
  }

  return true;

bad_command:
  // Errors are not reported via the usual mechanism. For rCmd, the usual
  // mechanism is for things like protocol errors. Instead we just want to
  // return the desired error message.
  callback(debugger_utils::EncodeString("Invalid command\n"));
  return true;
}

bool CommandHandler::HandleQuerySupported(const fxl::StringView& params,
                                          ResponseCallback callback) {
  // We ignore the parameters for qSupported. Respond with the supported
  // features.
  callback(kSupportedFeatures);
  return true;
}

bool CommandHandler::HandleSetNonStop(const fxl::StringView& params,
                                      ResponseCallback callback) {
  // The only values we accept are "1" and "0".
  if (params.size() != 1)
    return ReplyWithError(ErrorCode::INVAL, std::move(callback));

  // We currently only support non-stop mode.
  char value = params[0];
  if (value == '1')
    return ReplyOK(std::move(callback));

  if (value == '0')
    return ReplyWithError(ErrorCode::PERM, std::move(callback));

  FXL_LOG(ERROR) << "QNonStop received with invalid value: " << (unsigned)value;
  return ReplyWithError(ErrorCode::INVAL, std::move(callback));
}

bool CommandHandler::HandleQueryThreadInfo(bool is_first,
                                           ResponseCallback callback) {
  FXL_DCHECK(server_);

  inferior_control::Process* current_process = server_->current_process();
  if (!current_process) {
    FXL_LOG(ERROR) << "Current process is not set";
    return ReplyWithError(ErrorCode::PERM, std::move(callback));
  }

  // For the "first" thread info query we reply with the complete list of
  // threads and always report "end of list" for subsequent queries. The GDB
  // Remote Protocol does not seem to define a MTU, however, we could be running
  // on a platform with resource constraints that may require us to break up the
  // sequence into multiple packets. For now we do not worry about this.

  if (!is_first) {
    // This is a subsequent query. Check that a thread info query sequence was
    // started (just for sanity) and report end of list.
    if (!in_thread_info_sequence_) {
      FXL_LOG(ERROR) << "qsThreadInfo received without first receiving "
                     << "qfThreadInfo";
      return ReplyWithError(ErrorCode::PERM, std::move(callback));
    }

    in_thread_info_sequence_ = false;
    callback("l");
    return true;
  }

  // This is the first query. Check the sequence state for sanity.
  if (in_thread_info_sequence_) {
    FXL_LOG(ERROR) << "qfThreadInfo received while already in an active "
                   << "sequence";
    return ReplyWithError(ErrorCode::PERM, std::move(callback));
  }

  current_process->EnsureThreadMapFresh();

  std::deque<std::string> thread_ids;
  size_t buf_size = 0;
  current_process->ForEachLiveThread(
      [&thread_ids, &buf_size](inferior_control::Thread* thread) {
        std::string thread_id =
            fxl::NumberToString<zx_koid_t>(thread->id(), fxl::Base::k16);
        buf_size += thread_id.length();
        thread_ids.push_back(thread_id);
      });

  if (thread_ids.empty()) {
    // No ids to report. End of sequence.
    callback("l");
    return true;
  }

  in_thread_info_sequence_ = true;

  // Add the number of commas (|thread_ids.size() - 1|) plus the prefix "m")
  buf_size += thread_ids.size();

  std::unique_ptr<char[]> buffer(new char[buf_size]);
  buffer.get()[0] = 'm';
  debugger_utils::JoinStrings(thread_ids, ',', buffer.get() + 1, buf_size - 1);

  callback(fxl::StringView(buffer.get(), buf_size));

  return true;
}

bool CommandHandler::HandleQueryXfer(const fxl::StringView& params,
                                     ResponseCallback callback) {
  // We only support qXfer:auxv:read::
  // TODO(dje): TO-195
  // - qXfer::osdata::read::OFFSET,LENGTH
  // - qXfer:memory-map:read::OFFSET,LENGTH ?
  // - qXfer:libraries-svr4:read:ANNEX:OFFSET,LENGTH ?
  // - qXfer:features:read:ANNEX:OFFSET,LENGTH ?
  fxl::StringView auxv_read("auxv:read::");
  if (!StartsWith(params, auxv_read))
    return false;

  // Parse offset,length
  auto args = fxl::SplitString(params.substr(auxv_read.size()), ",",
                               fxl::kKeepWhitespace, fxl::kSplitWantNonEmpty);
  if (args.size() != 2) {
    FXL_LOG(ERROR) << "qXfer:auxv:read:: Malformed params: " << params;
    return ReplyWithError(ErrorCode::INVAL, std::move(callback));
  }

  size_t offset, length;
  if (!fxl::StringToNumberWithError<size_t>(args[0], &offset, fxl::Base::k16) ||
      !fxl::StringToNumberWithError<size_t>(args[1], &length, fxl::Base::k16)) {
    FXL_LOG(ERROR) << "qXfer:auxv:read:: Malformed params: " << params;
    return ReplyWithError(ErrorCode::INVAL, std::move(callback));
  }

  inferior_control::Process* current_process = server_->current_process();
  if (!current_process) {
    FXL_LOG(ERROR) << "qXfer:auxv:read: No current process is not set";
    return ReplyWithError(ErrorCode::PERM, std::move(callback));
  }

  // Build the auxiliary vector. This definition is provided by the Linux manual
  // page for the proc pseudo-filesystem (i.e. 'man proc'):
  // "This contains the contents of the ELF interpreter information passed to
  // the process at exec time. The format is one unsigned long ID plus one
  // unsigned long value for each entry. The last entry contains two zeros."
  // On Fuchsia we borrow this concept to save inventing something new.
  // We may have to eventually, but this works for now.
  // There is an extra complication that all the needed values aren't available
  // when the process starts: e.g., AT_ENTRY - the executable isn't loaded
  // until sometime after the process starts.
  constexpr size_t kMaxAuxvEntries = 10;
  struct {
    unsigned long key;
    unsigned long value;
  } auxv[kMaxAuxvEntries];

#define ADD_AUXV(_key, _value) \
  do {                         \
    auxv[n].key = (_key);      \
    auxv[n].value = (_value);  \
    ++n;                       \
  } while (0)

  size_t n = 0;
  ADD_AUXV(AT_BASE, current_process->base_address());
  if (current_process->DsosLoaded()) {
    const debugger_utils::dsoinfo_t* exec = current_process->GetExecDso();
    if (exec) {
      ADD_AUXV(AT_ENTRY, exec->entry);
      ADD_AUXV(AT_PHDR, exec->phdr);
      ADD_AUXV(AT_PHENT, exec->phentsize);
      ADD_AUXV(AT_PHNUM, exec->phnum);
    }
  }
  ADD_AUXV(AT_NULL, 0);
  FXL_DCHECK(n <= countof(auxv));

#undef ADD_AUXV

  // We allow setting sizeof(auxv) as the offset, which would effectively result
  // in reading 0 bytes.
  if (offset > sizeof(auxv)) {
    FXL_LOG(ERROR) << "qXfer:auxv:read: invalid offset";
    return ReplyWithError(ErrorCode::INVAL, std::move(callback));
  }

  size_t end = n * sizeof(auxv[0]);
  size_t rsp_len = std::min(end - offset, length);
  char rsp[1 + rsp_len];

  rsp[0] = 'l';
  memcpy(rsp + 1, auxv + offset, rsp_len);

  callback(fxl::StringView(rsp, sizeof(rsp)));
  return true;
}

bool CommandHandler::Handle_vAttach(const fxl::StringView& packet,
                                    ResponseCallback callback) {
  // TODO(dje): The terminology we use makes this confusing.
  // Here when you see "process" think "inferior". An inferior must be created
  // first, and then we can attach the inferior to a process.
  inferior_control::Process* current_process = server_->current_process();
  if (!current_process) {
    FXL_LOG(ERROR) << "vAttach: no inferior selected";
    return ReplyWithError(ErrorCode::PERM, std::move(callback));
  }

  zx_koid_t pid;
  if (!fxl::StringToNumberWithError<zx_koid_t>(packet, &pid, fxl::Base::k16)) {
    FXL_LOG(ERROR) << "vAttach:: Malformed pid: " << packet;
    return ReplyWithError(ErrorCode::INVAL, std::move(callback));
  }

  switch (current_process->state()) {
    case inferior_control::Process::State::kNew:
    case inferior_control::Process::State::kGone:
      break;
    default:
      FXL_LOG(ERROR)
          << "vAttach: need to kill the currently running process first";
      return ReplyWithError(ErrorCode::PERM, std::move(callback));
  }

  if (!current_process->Attach(pid)) {
    FXL_LOG(ERROR) << "vAttach: failed to attach to inferior " << pid;
    return ReplyWithError(ErrorCode::PERM, std::move(callback));
  }

  // It's Attach()'s job to mark the process as live, since it knows we just
  // attached to an already running program.
  FXL_DCHECK(current_process->IsLive());

  return ReplyOK(std::move(callback));
}

bool CommandHandler::Handle_vCont(const fxl::StringView& packet,
                                  ResponseCallback callback) {
  inferior_control::Process* current_process = server_->current_process();
  if (!current_process) {
    FXL_LOG(ERROR) << "vCont: no current process to run!";
    return ReplyWithError(ErrorCode::PERM, std::move(callback));
  }

  ThreadActionList actions(packet, current_process->id());
  if (!actions.valid()) {
    FXL_LOG(ERROR) << "vCont: \"" << packet << "\": error / not supported.";
    return ReplyWithError(ErrorCode::INVAL, std::move(callback));
  }

  FXL_DCHECK(current_process->IsLive());
  FXL_DCHECK(current_process->IsAttached());

  // Before we start calling GetAction we need to resolve "pick one" thread
  // values.
  for (auto e : actions.actions()) {
    if (e.tid() == 0) {
      FXL_DCHECK(e.pid() > 0);
      // TODO(dje): For now we assume there is only one process.
      FXL_DCHECK(current_process->id() == e.pid() ||
                 e.pid() == ThreadActionList::kAll);
      inferior_control::Thread* t = current_process->PickOneThread();
      if (t)
        e.set_picked_tid(t->id());
    }
  }
  actions.MarkPickOnesResolved();

  // First pass over all actions: Find any errors that we can so that we
  // don't cause any thread to run if there's an error.

  bool action_list_ok = true;
  current_process->ForEachLiveThread(
      [&actions, ok_ptr = &action_list_ok](inferior_control::Thread* thread) {
        zx_koid_t pid = thread->process()->id();
        zx_koid_t tid = thread->id();
        ThreadActionList::Action action = actions.GetAction(pid, tid);
        switch (action) {
          case ThreadActionList::Action::kStep:
            switch (thread->state()) {
              case inferior_control::Thread::State::kNew:
                FXL_LOG(ERROR) << "vCont;s: can't step thread in kNew state";
                *ok_ptr = false;
                return;
              default:
                break;
            }
          default:
            break;
        }
      });
  if (!action_list_ok)
    return ReplyWithError(ErrorCode::INVAL, std::move(callback));

  current_process->ForEachLiveThread(
      [&actions](inferior_control::Thread* thread) {
        zx_koid_t pid = thread->process()->id();
        zx_koid_t tid = thread->id();
        ThreadActionList::Action action = actions.GetAction(pid, tid);
        FXL_VLOG(1) << "vCont; Thread " << thread->GetDebugName()
                    << " state: " << thread->StateName(thread->state())
                    << " action: " << ThreadActionList::ActionToString(action);
        switch (action) {
          case ThreadActionList::Action::kContinue:
            switch (thread->state()) {
              case inferior_control::Thread::State::kNew:
              case inferior_control::Thread::State::kStopped:
                thread->Resume();
                break;
              default:
                break;
            }
          case ThreadActionList::Action::kStep:
            switch (thread->state()) {
              case inferior_control::Thread::State::kStopped:
                thread->Step();
                break;
              default:
                break;
            }
          default:
            break;
        }
      });

  // We defer sending a stop-reply packet. Server will send it out when threads
  // stop. At this point in time GDB is just expecting "OK".
  return ReplyOK(std::move(callback));
}

bool CommandHandler::Handle_vKill(const fxl::StringView& packet,
                                  ResponseCallback callback) {
  FXL_VLOG(2) << "Handle_vKill: " << packet;

  inferior_control::Process* current_process = server_->current_process();
  if (!current_process) {
    // This can't happen today, but it might eventually.
    FXL_LOG(ERROR) << "vRun: no current process to kill!";
    return ReplyWithError(ErrorCode::PERM, std::move(callback));
  }

  zx_koid_t pid;
  if (!fxl::StringToNumberWithError<zx_koid_t>(packet, &pid, fxl::Base::k16)) {
    FXL_LOG(ERROR) << "vAttach:: Malformed pid: " << packet;
    return ReplyWithError(ErrorCode::INVAL, std::move(callback));
  }

  // Since we only support one process at the moment, only allow killing
  // that one.
  if (pid != current_process->id()) {
    FXL_LOG(ERROR) << "vAttach:: not our pid: " << pid;
    return ReplyWithError(ErrorCode::INVAL, std::move(callback));
  }

  switch (current_process->state()) {
    case inferior_control::Process::State::kNew:
    case inferior_control::Process::State::kGone:
      FXL_LOG(ERROR) << "vKill: process not running";
      return ReplyWithError(ErrorCode::PERM, std::move(callback));
    default:
      break;
  }

  if (!current_process->Kill()) {
    FXL_LOG(ERROR) << "Failed to kill inferior";
    return ReplyWithError(ErrorCode::PERM, std::move(callback));
  }

  return ReplyOK(std::move(callback));
}

bool CommandHandler::Handle_vRun(const fxl::StringView& packet,
                                 ResponseCallback callback) {
  FXL_VLOG(2) << "Handle_vRun: " << packet;

  inferior_control::Process* current_process = server_->current_process();
  if (!current_process) {
    // This can't happen today, but it might eventually.
    FXL_LOG(ERROR) << "vRun: no current process to run!";
    return ReplyWithError(ErrorCode::PERM, std::move(callback));
  }

  if (!packet.empty()) {
    std::vector<std::string> argv = BuildArgvFor_vRun(packet);
    current_process->set_argv(argv);
  }

  switch (current_process->state()) {
    case inferior_control::Process::State::kNew:
    case inferior_control::Process::State::kGone:
      break;
    default:
      FXL_LOG(ERROR)
          << "vRun: need to kill the currently running process first";
      return ReplyWithError(ErrorCode::PERM, std::move(callback));
  }

  if (!current_process->Initialize()) {
    FXL_LOG(ERROR) << "Failed to set up inferior";
    return ReplyWithError(ErrorCode::PERM, std::move(callback));
  }

  // On Linux, the program is considered "live" after vRun, e.g. $pc is set. On
  // Zircon, calling zx_process_start (called by Process::Start()) creates a
  // synthetic exception of type ZX_EXCP_START if a debugger is attached to the
  // process and halts until a call to zx_task_resume (i.e. called by
  // Thread::Resume() in gdbserver).
  if (!current_process->Start()) {
    FXL_LOG(ERROR) << "vRun: Failed to start process";
    return ReplyWithError(ErrorCode::PERM, std::move(callback));
  }

  FXL_DCHECK(current_process->IsLive());

  // We defer sending a stop-reply packet. Server will send it out when it
  // receives an OnThreadStarting() event from |current_process|.

  return true;
}

bool CommandHandler::InsertSoftwareBreakpoint(
    uintptr_t addr, size_t kind, const fxl::StringView& optional_params,
    ResponseCallback callback) {
  FXL_VLOG(1) << fxl::StringPrintf(
      "Insert software breakpoint at %" PRIxPTR ", kind: %lu", addr, kind);

  inferior_control::Process* current_process = server_->current_process();
  if (!current_process) {
    FXL_LOG(ERROR) << "No current process exists";
    return ReplyWithError(ErrorCode::PERM, std::move(callback));
  }

  // TODO(armansito): Handle |optional_params|.

  if (!current_process->breakpoints()->InsertSoftwareBreakpoint(addr, kind)) {
    FXL_LOG(ERROR) << "Failed to insert software breakpoint";
    return ReplyWithError(ErrorCode::PERM, std::move(callback));
  }

  return ReplyOK(std::move(callback));
}

bool CommandHandler::RemoveSoftwareBreakpoint(uintptr_t addr, size_t kind,
                                              ResponseCallback callback) {
  FXL_VLOG(1) << fxl::StringPrintf("Remove software breakpoint at %" PRIxPTR,
                                   addr);

  inferior_control::Process* current_process = server_->current_process();
  if (!current_process) {
    FXL_LOG(ERROR) << "No current process exists";
    return ReplyWithError(ErrorCode::PERM, std::move(callback));
  }

  if (!current_process->breakpoints()->RemoveSoftwareBreakpoint(addr)) {
    FXL_LOG(ERROR) << "Failed to remove software breakpoint";
    return ReplyWithError(ErrorCode::PERM, std::move(callback));
  }

  return ReplyOK(std::move(callback));
}

}  // namespace debugserver
