// Copyright 2022 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 "fastboot.h"

#include <ctype.h>
#include <lib/abr/abr.h>
#include <lib/fastboot/fastboot_base.h>
#include <lib/storage/gpt_utils.h>
#include <lib/storage/sparse.h>
#include <lib/storage/storage.h>
#include <lib/zircon_boot/zircon_boot.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <xefi.h>

#include <algorithm>
#include <numeric>
#include <string>

#include <efi/string/string.h>
#include <efi/types.h>
#include <fbl/vector.h>
#include <phys/efi/main.h>
#include <pretty/hexdump.h>

#include "boot_zbi_items.h"
#include "gpt.h"
#include "lib/zx/result.h"
#include "utils.h"

namespace gigaboot {

static constexpr std::optional<AbrSlotIndex> ParseAbrSlotStr(std::string_view str, bool allow_r) {
  if (str == "a") {
    return kAbrSlotIndexA;
  } else if (str == "b") {
    return kAbrSlotIndexB;
  } else if (allow_r && str == "r") {
    return kAbrSlotIndexR;
  } else {
    return std::nullopt;
  }
}

zx::result<> Fastboot::ProcessCommand(std::string_view cmd, fastboot::Transport *transport) {
  auto cmd_table = GetCommandCallbackTable();
  for (const CommandCallbackEntry &ele : cmd_table) {
    if (MatchCommand(cmd, ele.name.data())) {
      return (this->*(ele.cmd))(cmd, transport);
    }
  }
  return SendResponse(ResponseType::kFail, "Unsupported command", transport);
}

void Fastboot::DoClearDownload() {}

zx::result<void *> Fastboot::GetDownloadBuffer(size_t total_download_size) {
  if (total_download_size > download_buffer_.size()) {
    return zx::error(ZX_ERR_BUFFER_TOO_SMALL);
  }
  return zx::ok(download_buffer_.data());
}

constexpr std::string_view kSlotArgs[] = {"a", "b"};

cpp20::span<Fastboot::VariableEntry> Fastboot::GetVariableTable() {
  static VariableEntry var_entries[] = {
      {"all", VarFuncAndArgs{&Fastboot::GetVarAll}},
      // Function based variables
      {"max-download-size", VarFuncAndArgs{&Fastboot::GetVarMaxDownloadSize}},
      {"current-slot", VarFuncAndArgs{&Fastboot::GetVarCurrentSlot}},
      {"slot-last-set-active", VarFuncAndArgs{&Fastboot::GetVarSlotLastSetActive}},
      {"slot-retry-count", VarFuncAndArgs{&Fastboot::GetVarSlotRetryCount, kSlotArgs}},
      {"slot-successful", VarFuncAndArgs{&Fastboot::GetVarSlotSuccessful, kSlotArgs}},
      {"slot-unbootable", VarFuncAndArgs{&Fastboot::GetVarSlotUnbootable, kSlotArgs}},
      // Constant based variables
      {"slot-count", {"2"}},
      {"slot-suffixes", {"a,b"}},
      {"hw-revision", {BOARD_NAME}},
      {"version", {"0.4"}},
  };

  return var_entries;
}

cpp20::span<Fastboot::CommandCallbackEntry> Fastboot::GetCommandCallbackTable() {
  static CommandCallbackEntry cmd_entries[] = {
      {"getvar", &Fastboot::GetVar},
      {"flash", &Fastboot::Flash},
      {"continue", &Fastboot::Continue},
      {"reboot", &Fastboot::Reboot},
      {"reboot-bootloader", &Fastboot::RebootBootloader},
      {"reboot-recovery", &Fastboot::RebootRecovery},
      {"set_active", &Fastboot::SetActive},
      {"oem gpt-init", &Fastboot::GptInit},
      {"oem add-staged-bootloader-file", &Fastboot::OemAddStagedBootloaderFile},
      {"oem efi-getvarinfo", &Fastboot::EfiGetVarInfo},
      {"oem efi-getvarnames", &Fastboot::EfiGetVarNames},
      {"oem efi-getvar", &Fastboot::EfiGetVar},
      {"oem efi-dumpvars", &Fastboot::EfiDumpVars},
  };

  return cmd_entries;
}

zx::result<> Fastboot::Reboot(std::string_view cmd, fastboot::Transport *transport) {
  return DoReboot(RebootMode::kNormal, cmd, transport);
}

zx::result<> Fastboot::RebootBootloader(std::string_view cmd, fastboot::Transport *transport) {
  return DoReboot(RebootMode::kBootloader, cmd, transport);
}

zx::result<> Fastboot::RebootRecovery(std::string_view cmd, fastboot::Transport *transport) {
  return DoReboot(RebootMode::kRecovery, cmd, transport);
}

zx::result<> Fastboot::DoReboot(RebootMode reboot_mode, std::string_view cmd,
                                fastboot::Transport *transport) {
  if (!SetRebootMode(reboot_mode)) {
    return SendResponse(ResponseType::kFail, "Failed to set reboot mode", transport,
                        zx::error(ZX_ERR_INTERNAL));
  }

  // ResetSystem() below won't return. Thus sends a OKAY response first in case we succeed.
  zx::result<> res = SendResponse(ResponseType::kOkay, "", transport);
  if (res.is_error()) {
    return res;
  }

  efi_status status =
      gEfiSystemTable->RuntimeServices->ResetSystem(EfiResetCold, EFI_SUCCESS, 0, NULL);
  if (status != EFI_SUCCESS) {
    printf("Failed to reboot: %s\n", EfiStatusToString(status));
    return zx::error(ZX_ERR_INTERNAL);
  }

  return zx::ok();
}

zx::result<> Fastboot::SetActive(std::string_view cmd, fastboot::Transport *transport) {
  CommandArgs args;
  ExtractCommandArgs(cmd, ":", args);

  if (args.num_args < 2) {
    return SendResponse(ResponseType::kFail, "missing slot name", transport);
  }

  std::optional<AbrSlotIndex> idx = ParseAbrSlotStr(args.args[1], false);
  if (!idx) {
    return SendResponse(ResponseType::kFail, "slot name is invalid", transport);
  }

  AbrOps abr_ops = GetAbrOps();
  AbrResult res = AbrMarkSlotActive(&abr_ops, *idx);
  if (res != kAbrResultOk) {
    return SendResponse(ResponseType::kFail, "Failed to set slot", transport,
                        zx::error(ZX_ERR_INTERNAL));
  }

  return SendResponse(ResponseType::kOkay, "", transport);
}

// Used to allow multiple single-type lambdas in std::visit
// instead of a single lambda with multiple constexpr if branches
template <class... Ts>
struct overload : Ts... {
  using Ts::operator()...;
};
template <class... Ts>
overload(Ts...) -> overload<Ts...>;

zx::result<> Fastboot::GetVar(std::string_view cmd, fastboot::Transport *transport) {
  CommandArgs args;
  ExtractCommandArgs(cmd, ":", args);
  if (args.num_args < 2) {
    return SendResponse(ResponseType::kFail, "Not enough arguments", transport);
  }
  auto var_table = GetVariableTable();
  for (const VariableEntry &ele : var_table) {
    if (args.args[1] == ele.name) {
      return std::visit(overload{
                            [this, &args, transport](const VarFuncAndArgs &entry) {
                              return (this->*(entry.func))(args, transport, DefaultResponder);
                            },
                            [transport](std::string_view arg) {
                              return SendResponse(ResponseType::kOkay, arg, transport);
                            },
                        },
                        ele.var);
    }
  }

  return SendResponse(ResponseType::kFail, "Unknown variable", transport);
}

// Inspired by python's str.join()
// Take a span of string_views
// (really could be any iterable/range of string-like objects),
// a delimiter character, and an output buffer, and put into the output buffer
// the concatenation of all the input strings, in order, with a single delimiter
// between each string.
//
// Note: empty strings are not treated specially. If any input strings are empty,
// the output will contain consecutive delimiters.
constexpr size_t StringJoin(cpp20::span<const std::string_view> names, char delimiter,
                            cpp20::span<char> buffer) {
  constexpr auto len_reducer = [](size_t sum, std::string_view val) { return sum + val.size(); };
  size_t total_length = std::reduce(names.begin(), names.end(), 0, len_reducer) + names.size() - 1;
  ZX_ASSERT(total_length <= buffer.size());

  size_t pos = 0;
  for (auto n : names) {
    pos += n.copy(&buffer[pos], n.size());
    // Don't add a trailing separator for the last string
    if (pos < total_length) {
      buffer[pos++] = delimiter;
    }
  }

  return total_length;
}

class GetVarAllResponder {
 public:
  explicit GetVarAllResponder(fbl::Vector<std::string_view> &args) : args_(args) {}

  zx::result<> operator()(Fastboot::ResponseType resp, std::string_view msg,
                          fastboot::Transport *transport) {
    if (resp == Fastboot::ResponseType::kFail) {
      return Fastboot::SendResponse(resp, msg, transport, zx::error(ZX_ERR_INTERNAL));
    }

    args_.push_back(msg);
    char buffer[fastboot::kMaxCommandPacketSize - sizeof("INFO")];
    cpp20::span<char> buffer_span(buffer, sizeof(buffer));
    size_t payload_len = StringJoin(args_, ':', buffer_span);
    args_.pop_back();
    buffer_span = {buffer, payload_len};

    return Fastboot::SendResponse(Fastboot::ResponseType::kInfo,
                                  std::string_view(buffer_span.data(), buffer_span.size()),
                                  transport);
  }

 private:
  fbl::Vector<std::string_view> &args_;
};

zx::result<> Fastboot::GetVarAll(const CommandArgs &, fastboot::Transport *transport,
                                 const Responder &resp) {
  for (const auto &var_entry : GetVariableTable()) {
    if (var_entry.name == "all") {
      continue;
    }

    fbl::Vector<std::string_view> strs = {var_entry.name};
    GetVarAllResponder responder(strs);

    if (std::holds_alternative<std::string_view>(var_entry.var)) {
      zx::result result =
          responder(ResponseType::kInfo, std::get<std::string_view>(var_entry.var), transport);
      if (result.is_error()) {
        return result;
      }
    } else if (std::holds_alternative<VarFuncAndArgs>(var_entry.var)) {
      const VarFuncAndArgs &vfa = std::get<VarFuncAndArgs>(var_entry.var);
      CommandArgs args = {.args = {"getvar", var_entry.name}, .num_args = 2};

      if (vfa.arg_list.empty()) {
        zx::result result = (this->*(vfa.func))(args, transport, responder);
        if (result.is_error()) {
          return result;
        }
      } else {
        args.num_args = 3;
        for (auto const arg : vfa.arg_list) {
          args.args[2] = arg;
          strs.push_back(arg);
          zx::result result = (this->*(vfa.func))(args, transport, responder);
          strs.pop_back();
          if (result.is_error()) {
            return result;
          }
        }
      }
    } else {
      ZX_ASSERT_MSG(false, "non-exhaustive visitation!");
    }
  }

  return resp(ResponseType::kOkay, "", transport);
}

zx::result<> Fastboot::GetVarMaxDownloadSize(const CommandArgs &, fastboot::Transport *transport,
                                             const Responder &resp) {
  char size_str[16] = {0};
  snprintf(size_str, sizeof(size_str), "0x%08zx", download_buffer_.size());
  return resp(ResponseType::kOkay, size_str, transport);
}

zx::result<> Fastboot::GetVarCurrentSlot(const CommandArgs &, fastboot::Transport *transport,
                                         const Responder &resp) {
  AbrOps abr_ops = GetAbrOps();

  char const *slot_str;
  AbrSlotIndex slot = AbrGetBootSlot(&abr_ops, false, nullptr);
  switch (slot) {
    case kAbrSlotIndexA:
      slot_str = "a";
      break;
    case kAbrSlotIndexB:
      slot_str = "b";
      break;
    case kAbrSlotIndexR:
      slot_str = "r";
      break;
    default:
      slot_str = "";
      break;
  }

  return resp(ResponseType::kOkay, slot_str, transport);
}

zx::result<> Fastboot::GetVarSlotLastSetActive(const CommandArgs &, fastboot::Transport *transport,
                                               const Responder &resp) {
  AbrOps abr_ops = GetAbrOps();
  AbrSlotIndex slot;
  AbrResult res = AbrGetSlotLastMarkedActive(&abr_ops, &slot);
  if (res != kAbrResultOk) {
    return resp(ResponseType::kFail, "Failed to get slot last set active", transport);
  }
  // The slot is guaranteed not to be r if the result is okay.
  const char *slot_str = slot == kAbrSlotIndexA ? "a" : "b";

  return resp(ResponseType::kOkay, slot_str, transport);
}

zx::result<> Fastboot::GetVarSlotRetryCount(const CommandArgs &args, fastboot::Transport *transport,
                                            const Responder &resp) {
  if (args.num_args < 3) {
    return resp(ResponseType::kFail, "Not enough arguments", transport);
  }

  std::optional<AbrSlotIndex> idx = ParseAbrSlotStr(args.args[2], false);
  if (!idx) {
    return resp(ResponseType::kFail, "slot name is invalid", transport);
  }

  AbrOps abr_ops = GetAbrOps();
  AbrSlotInfo info;
  AbrResult res = AbrGetSlotInfo(&abr_ops, *idx, &info);
  if (res != kAbrResultOk) {
    return resp(ResponseType::kFail, "Failed to get slot retry count", transport);
  }

  char retry_str[16] = {0};
  snprintf(retry_str, sizeof(retry_str), "%u", info.num_tries_remaining);

  return resp(ResponseType::kOkay, retry_str, transport);
}

zx::result<> Fastboot::GetVarSlotSuccessful(const CommandArgs &args, fastboot::Transport *transport,
                                            const Responder &resp) {
  if (args.num_args < 3) {
    return resp(ResponseType::kFail, "Not enough arguments", transport);
  }

  std::optional<AbrSlotIndex> idx = ParseAbrSlotStr(args.args[2], true);
  if (!idx) {
    return resp(ResponseType::kFail, "slot name is invalid", transport);
  }

  AbrOps abr_ops = GetAbrOps();
  AbrSlotInfo info;
  AbrResult res = AbrGetSlotInfo(&abr_ops, *idx, &info);
  if (res != kAbrResultOk) {
    return resp(ResponseType::kFail, "Failed to get slot successful", transport);
  }

  return resp(ResponseType::kOkay, info.is_marked_successful ? "yes" : "no", transport);
}

zx::result<> Fastboot::GetVarSlotUnbootable(const CommandArgs &args, fastboot::Transport *transport,
                                            const Responder &resp) {
  if (args.num_args < 3) {
    return resp(ResponseType::kFail, "Not enough arguments", transport);
  }

  std::optional<AbrSlotIndex> idx = ParseAbrSlotStr(args.args[2], true);
  if (!idx) {
    return resp(ResponseType::kFail, "slot name is invalid", transport);
  }

  AbrOps abr_ops = GetAbrOps();
  AbrSlotInfo info;
  AbrResult res = AbrGetSlotInfo(&abr_ops, *idx, &info);
  if (res != kAbrResultOk) {
    return resp(ResponseType::kFail, "Failed to get slot unbootable", transport);
  }

  return resp(ResponseType::kOkay, info.is_bootable ? "no" : "yes", transport);
}

class GptDataHolder {
 public:
  explicit GptDataHolder(FuchsiaFirmwareStorage &ops) : ops_(ops) {}
  ~GptDataHolder() { ZX_ASSERT(FuchsiaFirmwareStorageFreeGptData(&ops_, &data_)); }
  GptData &Data() { return data_; }

 private:
  GptData data_;
  FuchsiaFirmwareStorage &ops_;
};

zx::result<> Fastboot::Flash(std::string_view cmd, fastboot::Transport *transport) {
  CommandArgs args;
  ExtractCommandArgs(cmd, ":", args);
  if (args.num_args < 2) {
    return SendResponse(ResponseType::kFail, "Not enough argument", transport);
  }

  auto device = FindEfiGptDevice();
  if (device.is_error() || device->Load().is_error()) {
    return SendResponse(ResponseType::kFail, "Failed to get block device", transport,
                        zx::error(ZX_ERR_INTERNAL));
  }

  ZX_ASSERT(args.args[1].size() < fastboot::kMaxCommandPacketSize);
  char part_name_data[fastboot::kMaxCommandPacketSize] = {};
  memcpy(part_name_data, args.args[1].data(), args.args[1].size());
  std::string_view part_name = MaybeMapPartitionName(*device, part_name_data);

  FuchsiaFirmwareStorage ops = device->GenerateStorageOps();
  GptDataHolder gpt_data(ops);
  if (!FuchsiaFirmwareStorageSyncGpt(&ops, &gpt_data.Data())) {
    return SendResponse(ResponseType::kFail, "Failed to sync gpt data", transport,
                        zx::error(ZX_ERR_INTERNAL));
  }

  bool res;
  if (FuchsiaIsSparseImage(download_buffer_.data(), total_download_size())) {
    res = FuchsiaWriteSparseImage(&ops, &gpt_data.Data(), part_name.data(), download_buffer_.data(),
                                  total_download_size());
  } else {
    res = FuchsiaFirmwareStorageGptWrite(&ops, &gpt_data.Data(), part_name.data(), 0,
                                         total_download_size(), download_buffer_.data());
  }

  if (!res) {
    return SendResponse(ResponseType::kFail, "Failed to write to partition", transport,
                        zx::error(ZX_ERR_INTERNAL));
  }

  return SendResponse(ResponseType::kOkay, "", transport);
}

zx::result<> Fastboot::GptInit(std::string_view cmd, fastboot::Transport *transport) {
  auto device = FindEfiGptDevice();
  if (!device.is_ok()) {
    return SendResponse(ResponseType::kFail, "Failed to get block device", transport,
                        zx::error(ZX_ERR_INTERNAL));
  }

  auto res = device.value().Reinitialize();
  if (!res.is_ok()) {
    return SendResponse(ResponseType::kFail, "Failed to reinitialize partiions", transport,
                        zx::error(ZX_ERR_INTERNAL));
  }

  return SendResponse(ResponseType::kOkay, "", transport);
}

fbl::Vector<char> StringPrintf(const char *fmt, va_list va) {
  fbl::Vector<char> buf{'\0'};
  va_list va2;
  va_copy(va2, va);
  const size_t len = vsnprintf(buf.data(), 0, fmt, va);
  buf.resize(len + 1);
  vsnprintf(buf.data(), buf.size(), fmt, va2);
  va_end(va2);
  buf.pop_back();
  return buf;
}

void Fastboot::InfoSend(fastboot::Transport *transport, const char *fmt, va_list va) {
  fbl::Vector<char> s = StringPrintf(fmt, va);
  if (Fastboot::SendResponse(Fastboot::ResponseType::kInfo, s.data(), transport).is_error()) {
    printf("Failed to send Info response.\n");
  }
}

zx::result<> Fastboot::EfiGetVarInfo(std::string_view cmd, fastboot::Transport *transport) {
  auto info = efi_variables_->EfiQueryVariableInfo();
  auto transport_scope = RegisterTransport(transport);

  if (info.is_error()) {
    return SendResponse(ResponseType::kFail, "QueryVariableInfo() failed", transport);
  }

  printer_(
      "\n"
      "  Max Storage Size: %" PRIu64
      "\n"
      "  Remaining Variable Storage Size: %" PRIu64
      "\n"
      "  Max Variable Size: %" PRIu64 "\n",
      info.value().max_var_storage_size, info.value().remaining_var_storage_size,
      info.value().max_var_size);

  return SendResponse(ResponseType::kOkay, "", transport);
}

zx::result<> Fastboot::EfiGetVarNames(std::string_view cmd, fastboot::Transport *transport) {
  auto transport_scope = RegisterTransport(transport);

  for (auto v_id : *efi_variables_) {
    if (!v_id.IsValid()) {
      return SendResponse(ResponseType::kFail, "EfiVariableName iteration failed", transport);
    }

    const auto &guid = v_id.vendor_guid;
    printer_("%s %s\n", ToStr(guid).data(), v_id.name.c_str());
  }
  printer_("\n");

  return SendResponse(ResponseType::kOkay, "", transport);
}

void hexdump_printer_printf(void *printf_arg, const char *fmt, ...) {
  Fastboot *obj = static_cast<Fastboot *>(printf_arg);
  va_list args;
  va_start(args, fmt);
  obj->vprinter_(fmt, args);
  va_end(args);
}

// Hex dump function with shortened output line length. Mostly taken from:
// http://cs/fuchsia/zircon/system/ulib/pretty/hexdump.cc
// void hexdump8_very_ex(const void* ptr, size_t len, uint64_t disp_addr, hexdump_printf_func_t*
// printf_func, void* printf_arg);
//
// It differs from original in:
//  - offset column removed
//  - spaces between quartets of bytes are removed
//
// Output format looks like:
// ```
//  01010102 00000100 00000000 00000001 |................
//  00                                  |.
// ```
//
// Short hexdump version is required to make it readable when send via kInfo channel.
// In order to make it easier to use with kInfo channel this function calls `printf_func` only to
// print full line.
void hexdump8_short(const void *ptr, size_t len, hexdump_printf_func_t *printf_func,
                    void *printf_arg) {
  const uint8_t *address = reinterpret_cast<const uint8_t *>(ptr);
  char line_buffer[fastboot::kMaxCommandPacketSize + 1];

  for (size_t count = 0; count < len; count += 16) {
    cpp20::span<char> remaining(line_buffer);
    size_t used = 0;

    size_t i;
    for (i = 0; i < std::min(len - count, size_t{16}); i++) {
      used = snprintf(remaining.data(), remaining.size(), "%02hhx%s", *(address + i),
                      (i % 4 == 3) ? " " : "");
      remaining = remaining.subspan(used);
    }

    for (; i < 16; i++) {
      used = snprintf(remaining.data(), remaining.size(), "%s", (i % 4 == 3) ? "   " : "  ");
      remaining = remaining.subspan(used);
    }

    used = snprintf(remaining.data(), remaining.size(), "|");
    remaining = remaining.subspan(used);

    for (i = 0; i < std::min(len - count, size_t{16}); i++) {
      char c = address[i];
      used = snprintf(remaining.data(), remaining.size(), "%c", isprint(c) ? c : '.');
      remaining = remaining.subspan(used);
    }

    used = snprintf(remaining.data(), remaining.size(), "\n");
    remaining = remaining.subspan(used);

    printf_func(printf_arg, line_buffer);
    address += 16;
  }
}

// This function expects `cmd` in following format:
// oem efi-getvar <var_name> [<guid>]
//
// E.g.
//  oem efi-getvar BootOrder
//  oem efi-getvar BootOrder 8be4df61-93ca-11d2-aa0d-00e098032b8c
zx::result<> Fastboot::EfiGetVar(std::string_view cmd, fastboot::Transport *transport) {
  auto transport_scope = RegisterTransport(transport);

  CommandArgs args;
  ExtractCommandArgs(cmd, " ", args);

  if (args.num_args < 3 || args.num_args > 4) {
    return SendResponse(ResponseType::kFail,
                        "Bad number of arguments."
                        " Expected format: oem efi-getvar <var_name> [<guid>]",
                        transport);
  }

  const std::string_view in_var_name = args.args[2];
  efi::String var_name = efi::String(in_var_name);
  if (!var_name.IsValid()) {
    printer_("UTF8->UC2 convertion failed for variable name: '%s'\n", in_var_name.data());
    return SendResponse(ResponseType::kFail, "UTF8->UC2 convertion failed for variable name",
                        transport);
  }

  efi_guid guid;
  if (args.num_args == 4) {
    std::string_view guid_str = args.args[3];
    auto res_guid = ToGuid(guid_str);
    if (res_guid.is_error()) {
      printer_("Vendor GUID parsing failed (%s) for: '%s'\n", xefi_strerror(res_guid.error_value()),
               guid_str.data());
      return SendResponse(ResponseType::kFail, "Vendor GUID parsing failed", transport);
    }
    guid = res_guid.value();
  } else if (args.num_args == 3) {
    auto res_guid = efi_variables_->GetGuid(var_name);
    if (res_guid.is_error()) {
      printer_("Vendor GUID search failed (%s) for: '%s'\n", xefi_strerror(res_guid.error_value()),
               var_name.c_str());
      if (res_guid.error_value() == EFI_INVALID_PARAMETER) {
        return SendResponse(ResponseType::kFail,
                            "Multiple entries found with specified name. Please provide GUID",
                            transport);
      } else {
        return SendResponse(ResponseType::kFail, "Vendor GUID search failed", transport);
      }
    }
    guid = res_guid.value();
  }

  // Print VariableName
  efi::VariableId v_id{std::move(var_name), guid};
  if (!v_id.name.IsValid()) {
    const auto err_str = "Failed to convert UCS2 variable name to UTF8\n";
    printer_(err_str);
    return SendResponse(ResponseType::kFail, err_str, transport);
  }
  printer_("%s %s:\n", ToStr(guid).data(), v_id.name.c_str());

  // Get and print Value
  auto res_get_var = efi_variables_->EfiGetVariable(v_id);
  if (res_get_var.is_error()) {
    return SendResponse(ResponseType::kFail, "GetVariable() failed", transport);
  }
  hexdump8_short(res_get_var.value().data(), res_get_var.value().size(), hexdump_printer_printf,
                 this);

  return SendResponse(ResponseType::kOkay, "", transport);
}

int Fastboot::printer_(const char *fmt, ...) {
  va_list args;
  va_start(args, fmt);
  int res = vprinter_(fmt, args);
  va_end(args);
  return res;
}

zx::result<> Fastboot::EfiDumpVars(std::string_view cmd, fastboot::Transport *transport) {
  auto transport_scope = RegisterTransport(transport);
  for (const auto &v_id : *efi_variables_) {
    if (!v_id.IsValid())
      return SendResponse(ResponseType::kFail, "EfiVariableName iteration failed", transport);

    const auto &guid = v_id.vendor_guid;
    printer_("%s %s:\n", ToStr(guid).data(), v_id.name.c_str());

    auto res = efi_variables_->EfiGetVariable(v_id);
    if (res.is_error()) {
      printer_("Failed to get variable\n");
      continue;
    }

    auto &val = res.value();
    hexdump8_short(val.data(), val.size(), hexdump_printer_printf, this);
  }
  printer_("\n");

  return SendResponse(ResponseType::kOkay, "", transport);
}

zx::result<> Fastboot::Continue(std::string_view cmd, fastboot::Transport *transport) {
  continue_ = true;
  return SendResponse(ResponseType::kOkay, "", transport);
}

zx::result<> Fastboot::OemAddStagedBootloaderFile(std::string_view cmd,
                                                  fastboot::Transport *transport) {
  CommandArgs args;
  ExtractCommandArgs(cmd, " ", args);
  if (args.num_args != 3) {
    return SendResponse(ResponseType::kFail, "Not enough argument", transport);
  }

  zbi_result_t res =
      AddBootloaderFiles(args.args[2].data(), download_buffer_.data(), total_download_size());
  if (res != ZBI_RESULT_OK) {
    printf("Failed to append zbi_files: %d\n", res);
    return SendResponse(ResponseType::kFail, "Failed to initialize zbi file", transport,
                        zx::error(ZX_ERR_INTERNAL));
  }

  return SendResponse(ResponseType::kOkay, "", transport);
}

using FastbootState = fastboot::FastbootBase::State;

// The transport implementation for a TCP fastboot packet.
class PacketTransport : public fastboot::Transport {
 public:
  PacketTransport(TcpTransportInterface &interface, size_t packet_size, Fastboot &fastboot)
      : interface_(&interface),
        packet_size_(packet_size),
        fastboot_(&fastboot),
        last_state_(fastboot.state()) {}

  zx::result<size_t> ReceivePacket(void *dst, size_t capacity) override {
    if (packet_size_ > capacity) {
      return zx::error(ZX_ERR_BUFFER_TOO_SMALL);
    }

    if (!interface_->Read(dst, packet_size_)) {
      return zx::error(ZX_ERR_INTERNAL);
    }

    if (last_state_ == FastbootState::kCommand) {
      printf("[fb] %.*s ... ", static_cast<int>(packet_size_), static_cast<char *>(dst));
    }

    return zx::ok(packet_size_);
  }

  // Peek the size of the next packet.
  size_t PeekPacketSize() override { return packet_size_; }

  zx::result<> Send(std::string_view packet) override {
    // The first packet within the data phase is logged so the DATA response is
    // shown. Subsequent packets are not logged until it reenters the command
    // phase.
    auto state = fastboot_->state();
    if (state == FastbootState::kCommand || last_state_ == FastbootState::kCommand) {
      printf("%.*s\n", static_cast<int>(packet.size()), packet.data());
      last_state_ = state;
    }

    // Prepend a length prefix.
    size_t size = packet.size();
    uint64_t be_size = ToBigEndian(size);
    if (!interface_->Write(&be_size, sizeof(be_size))) {
      return zx::error(ZX_ERR_INTERNAL);
    }

    if (!interface_->Write(packet.data(), size)) {
      return zx::error(ZX_ERR_INTERNAL);
    }

    return zx::ok();
  }

 private:
  TcpTransportInterface *interface_ = nullptr;
  size_t packet_size_ = 0;
  Fastboot *fastboot_ = nullptr;
  FastbootState last_state_ = FastbootState::kCommand;
};

void FastbootTcpSession(TcpTransportInterface &interface, Fastboot &fastboot) {
  // Whatever we receive, sends a handshake message first to improve performance.
  printf("Fastboot connection established\n");
  if (!interface.Write("FB01", 4)) {
    printf("Failed to write handshake message\n");
    return;
  }

  char handshake_buffer[kFastbootHandshakeMessageLength + 1] = {0};
  if (!interface.Read(handshake_buffer, kFastbootHandshakeMessageLength)) {
    printf("Failed to read handshake message\n");
    return;
  }

  // We expect "FBxx", where xx is a numeric value
  if (strncmp(handshake_buffer, "FB", 2) != 0 || !isdigit(handshake_buffer[2]) ||
      !isdigit(handshake_buffer[3])) {
    printf("Invalid handshake message %s\n", handshake_buffer);
    return;
  }

  while (true) {
    // Each fastboot packet is a length-prefixed data sequence. Read the length
    // prefix first.
    uint64_t packet_length = 0;
    if (!interface.Read(&packet_length, sizeof(packet_length))) {
      printf("Failed to read length prefix. Remote client might be disconnected\n");
      return;
    }

    // Process the length prefix. Convert big-endian to integer.
    packet_length = BigToHostEndian(packet_length);

    // Construct and pass a packet transport to fastboot.
    PacketTransport packet(interface, packet_length, fastboot);
    zx::result<> ret = fastboot.ProcessPacket(&packet);
    if (ret.is_error()) {
      printf("Failed to process fastboot packet\n");
      return;
    }

    if (fastboot.IsContinue()) {
      printf("Resuming boot...\n");
      return;
    }
  }
}

}  // namespace gigaboot
