// 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 "utils.h"

#include <bootbyte.h>
#include <ctype.h>
#include <lib/abr/abr.h>
#include <lib/zbi-format/memory.h>
#include <lib/zbi/zbi.h>
#include <stdio.h>
#include <zircon/hw/gpt.h>

#include <algorithm>

#include <efi/global-variable.h>
#include <efi/types.h>
#include <fbl/string_printf.h>

#include "gpt.h"

namespace gigaboot {

namespace {

std::optional<RebootMode> ParseByteToRebootMode(uint8_t b) {
  switch (b) {
    case 0x1:
      return RebootMode::kNormal;
    case 0x2:
      return RebootMode::kRecovery;
    case 0x4:
      return RebootMode::kBootloader;
    case 0xFF:
      return RebootMode::kBootloaderDefault;
    default:
      return std::nullopt;
  }
}

}  // namespace

const char* EfiStatusToString(efi_status status) {
  switch (status) {
#define ERR_ENTRY(x) \
  case x: {          \
    return #x;       \
  }
    ERR_ENTRY(EFI_SUCCESS);
    ERR_ENTRY(EFI_LOAD_ERROR);
    ERR_ENTRY(EFI_INVALID_PARAMETER);
    ERR_ENTRY(EFI_UNSUPPORTED);
    ERR_ENTRY(EFI_BAD_BUFFER_SIZE);
    ERR_ENTRY(EFI_BUFFER_TOO_SMALL);
    ERR_ENTRY(EFI_NOT_READY);
    ERR_ENTRY(EFI_DEVICE_ERROR);
    ERR_ENTRY(EFI_WRITE_PROTECTED);
    ERR_ENTRY(EFI_OUT_OF_RESOURCES);
    ERR_ENTRY(EFI_VOLUME_CORRUPTED);
    ERR_ENTRY(EFI_VOLUME_FULL);
    ERR_ENTRY(EFI_NO_MEDIA);
    ERR_ENTRY(EFI_MEDIA_CHANGED);
    ERR_ENTRY(EFI_NOT_FOUND);
    ERR_ENTRY(EFI_ACCESS_DENIED);
    ERR_ENTRY(EFI_NO_RESPONSE);
    ERR_ENTRY(EFI_NO_MAPPING);
    ERR_ENTRY(EFI_TIMEOUT);
    ERR_ENTRY(EFI_NOT_STARTED);
    ERR_ENTRY(EFI_ALREADY_STARTED);
    ERR_ENTRY(EFI_ABORTED);
    ERR_ENTRY(EFI_ICMP_ERROR);
    ERR_ENTRY(EFI_TFTP_ERROR);
    ERR_ENTRY(EFI_PROTOCOL_ERROR);
    ERR_ENTRY(EFI_INCOMPATIBLE_VERSION);
    ERR_ENTRY(EFI_SECURITY_VIOLATION);
    ERR_ENTRY(EFI_CRC_ERROR);
    ERR_ENTRY(EFI_END_OF_MEDIA);
    ERR_ENTRY(EFI_END_OF_FILE);
    ERR_ENTRY(EFI_INVALID_LANGUAGE);
    ERR_ENTRY(EFI_COMPROMISED_DATA);
    ERR_ENTRY(EFI_IP_ADDRESS_CONFLICT);
    ERR_ENTRY(EFI_HTTP_ERROR);
    ERR_ENTRY(EFI_CONNECTION_FIN);
    ERR_ENTRY(EFI_CONNECTION_RESET);
    ERR_ENTRY(EFI_CONNECTION_REFUSED);
#undef ERR_ENTRY
  }

  return "<Unknown error>";
}

// Converts an EFI memory type to a zbi_mem_range_t type.
uint32_t EfiToZbiMemRangeType(uint32_t efi_mem_type) {
  switch (efi_mem_type) {
    case EfiLoaderCode:
    case EfiLoaderData:
    case EfiBootServicesCode:
    case EfiBootServicesData:
    case EfiConventionalMemory:
      return ZBI_MEM_TYPE_RAM;
  }
  return ZBI_MEM_TYPE_RESERVED;
}

uint64_t ToBigEndian(uint64_t val) {
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
  return __builtin_bswap64(val);
#else
  return val;
#endif
}

uint64_t BigToHostEndian(uint64_t val) { return ToBigEndian(val); }

efi_status PrintTpm2Capability() {
  auto tpm2_protocol = gigaboot::EfiLocateProtocol<efi_tcg2_protocol>();
  if (tpm2_protocol.is_error()) {
    return tpm2_protocol.error_value();
  }

  printf("Found TPM 2.0 EFI protocol.\n");

  // Log TPM capability
  efi_tcg2_boot_service_capability capability;
  efi_status status = tpm2_protocol->GetCapability(tpm2_protocol.value().get(), &capability);
  if (status != EFI_SUCCESS) {
    return status;
  }

  printf("TPM 2.0 Capabilities:\n");

#define PRINT_NAMED_VAL(field, format) printf(#field " = " format "\n", (field))

  // Structure version
  PRINT_NAMED_VAL(capability.StructureVersion.Major, "0x%02x");
  PRINT_NAMED_VAL(capability.StructureVersion.Minor, "0x%02x");

  // Protocol version
  PRINT_NAMED_VAL(capability.ProtocolVersion.Major, "0x%02x");
  PRINT_NAMED_VAL(capability.ProtocolVersion.Minor, "0x%02x");

#define PRINT_NAMED_BIT(flags, bit) printf(#flags "." #bit "= %d\n", ((flags) & (bit)) ? 1 : 0)

  // Supported hash algorithms
  PRINT_NAMED_BIT(capability.HashAlgorithmBitmap, EFI_TCG2_BOOT_HASH_ALG_SHA1);
  PRINT_NAMED_BIT(capability.HashAlgorithmBitmap, EFI_TCG2_BOOT_HASH_ALG_SHA256);
  PRINT_NAMED_BIT(capability.HashAlgorithmBitmap, EFI_TCG2_BOOT_HASH_ALG_SHA384);
  PRINT_NAMED_BIT(capability.HashAlgorithmBitmap, EFI_TCG2_BOOT_HASH_ALG_SHA512);
  PRINT_NAMED_BIT(capability.HashAlgorithmBitmap, EFI_TCG2_BOOT_HASH_ALG_SM3_256);

  // Supported event logs
  PRINT_NAMED_BIT(capability.SupportedEventLogs, EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2);
  PRINT_NAMED_BIT(capability.SupportedEventLogs, EFI_TCG2_EVENT_LOG_FORMAT_TCG_2);

  // Others
  PRINT_NAMED_VAL(capability.ProtocolVersion.Minor, "0x%02x");
  PRINT_NAMED_VAL(capability.TPMPresentFlag, "0x%02x");
  PRINT_NAMED_VAL(capability.MaxCommandSize, "0x%04x");
  PRINT_NAMED_VAL(capability.MaxResponseSize, "0x%04x");
  PRINT_NAMED_VAL(capability.ManufacturerID, "0x%08x");
  PRINT_NAMED_VAL(capability.NumberOfPcrBanks, "0x%08x");
  PRINT_NAMED_VAL(capability.ActivePcrBanks, "0x%08x");

#undef PRINT_NAMED_VAL
#undef PRINT_NAMED_BIT

  return EFI_SUCCESS;
}

fit::result<efi_status, bool> IsSecureBootOn() {
  size_t size = 1;
  uint8_t value;
  char16_t name[] = u"SecureBoot";
  efi_guid global_var_guid = GlobalVariableGuid;
  efi_status status =
      gEfiSystemTable->RuntimeServices->GetVariable(name, &global_var_guid, NULL, &size, &value);
  if (status != EFI_SUCCESS) {
    return fit::error(status);
  }

  return fit::ok(value);
}

std::string_view MaybeMapPartitionName(const EfiGptBlockDevice& device,
                                       std::string_view partition) {
  struct partition_names {
    std::string_view legacy;
    std::string_view modern;
  };
  constexpr partition_names names[]{
      {GUID_ABR_META_NAME, GPT_DURABLE_BOOT_NAME},
      {GUID_ZIRCON_A_NAME, GPT_ZIRCON_A_NAME},
      {GUID_ZIRCON_B_NAME, GPT_ZIRCON_B_NAME},
      {GUID_ZIRCON_R_NAME, GPT_ZIRCON_R_NAME},
      {GUID_FVM_NAME, GPT_FVM_NAME},
  };

  auto name_entry =
      std::find_if(std::begin(names), std::end(names),
                   [&partition](const auto& entry) { return entry.modern == partition; });
  if (name_entry == std::end(names)) {
    // This is some other partition without a legacy naming scheme that we care about.
    return partition;
  }

  for (const auto& p : device.ListPartitionNames()) {
    if (p.data() == name_entry->legacy) {
      return name_entry->legacy;
    }
    if (p.data() == name_entry->modern) {
      return name_entry->modern;
    }
  }

  // Should never reach here.
  return partition;
}

// TODO(b/285053546) 'BootByte' usage should be removed in favour of ABR Metadata
bool SetRebootMode(RebootMode mode) {
  return gEfiSystemTable != nullptr &&
         set_bootbyte(gEfiSystemTable->RuntimeServices, RebootModeToByte(mode)) == EFI_SUCCESS;
}

std::optional<RebootMode> GetRebootMode(AbrDataOneShotFlags one_shot_flags) {
  if (AbrIsOneShotRecoveryBootSet(one_shot_flags)) {
    return RebootMode::kRecovery;
  }
  if (AbrIsOneShotBootloaderBootSet(one_shot_flags)) {
    return RebootMode::kBootloader;
  }

  // TODO(b/285053546) 'BootByte' usage should be removed in favour of ABR Metadata
  uint8_t bootbyte;
  efi_status status = get_bootbyte(gEfiSystemTable->RuntimeServices, &bootbyte);
  if (status != EFI_SUCCESS) {
    return std::nullopt;
  }

  return ParseByteToRebootMode(bootbyte);
}

// See `ToStr()` for format details
// Expected input string should be in following format: "aabbccdd-eeff-gghh-iijj-kkllmmnnoopp"
fit::result<efi_status, efi_guid> ToGuid(std::string_view guid_str) {
  efi_guid guid;

  auto ParseByte = [](std::string_view& str, uint8_t& output) -> bool {
    if (str.size() < kByteToHexLen) {
      return false;
    }

    if (!std::all_of(str.begin(), str.begin() + kByteToHexLen, isxdigit)) {
      return false;
    }

    char c_str[kByteToHexLen + 1];
    str.copy(c_str, kByteToHexLen);
    c_str[kByteToHexLen] = '\0';
    output = static_cast<uint8_t>(strtoul(c_str, nullptr, 16));
    str = str.substr(kByteToHexLen);
    return true;
  };

  auto ParseDash = [](std::string_view& str) -> bool {
    constexpr size_t kInputLen = 1;
    if (str.size() < kInputLen) {
      return false;
    }
    if (str[0] != '-') {
      return false;
    }
    str = str.substr(kInputLen);
    return true;
  };

  cpp20::span<uint8_t> buf(reinterpret_cast<uint8_t*>(&guid), sizeof(guid));
  if (ParseByte(guid_str, buf[3]) &&   // |   aa   |    3      |
      ParseByte(guid_str, buf[2]) &&   // |   bb   |    2      |
      ParseByte(guid_str, buf[1]) &&   // |   cc   |    1      |
      ParseByte(guid_str, buf[0]) &&   // |   dd   |    0      |
      ParseDash(guid_str) &&           // |   -    |    -      |
      ParseByte(guid_str, buf[5]) &&   // |   ee   |    5      |
      ParseByte(guid_str, buf[4]) &&   // |   ff   |    4      |
      ParseDash(guid_str) &&           // |   -    |    -      |
      ParseByte(guid_str, buf[7]) &&   // |   gg   |    7      |
      ParseByte(guid_str, buf[6]) &&   // |   hh   |    6      |
      ParseDash(guid_str) &&           // |   -    |    -      |
      ParseByte(guid_str, buf[8]) &&   // |   ii   |    8      |
      ParseByte(guid_str, buf[9]) &&   // |   jj   |    9      |
      ParseDash(guid_str) &&           // |   -    |    -      |
      ParseByte(guid_str, buf[10]) &&  // |   kk   |   10      |
      ParseByte(guid_str, buf[11]) &&  // |   ll   |   11      |
      ParseByte(guid_str, buf[12]) &&  // |   mm   |   12      |
      ParseByte(guid_str, buf[13]) &&  // |   nn   |   13      |
      ParseByte(guid_str, buf[14]) &&  // |   oo   |   14      |
      ParseByte(guid_str, buf[15]) &&  // |   pp   |   15      |
      guid_str.empty()) {
    return fit::ok(guid);
  }

  return fit::error(EFI_INVALID_PARAMETER);
}

// String format is specified at https://www.rfc-editor.org/rfc/rfc4122
// And also described here: https://uefi.org/specs/UEFI/2.10/Apx_A_GUID_and_Time_Formats.html
// This specification also defines a standard text representation of the GUID. This format is also
// sometimes called the “registry format”. It consists of 36 characters, as follows:
//
//  `aabbccdd-eeff-gghh-iijj-kkllmmnnoopp`
//
// The pairs aa - pp are two characters in the range ‘0’ -‘9’, ‘a’ -‘f’ or ‘A’ - F’, with each pair
// representing a single byte hexadecimal value.
//
// The following table describes the relationship between the text representation and a 16 - byte
// buffer, the structure defined in EFI GUID Format and the EFI_GUID structure.
//
// +--------+-----------+--------------------------------+-----------------+
// | String | Offset In | Relationship to EFI GUID       | Relationship To |
// |        | Buffer    | Format                         | EFI_GUID        |
// +--------+-----------+--------------------------------+-----------------+
// |   aa   |    3      | TimeLow[24:31]                 | Data1[24:31]    |
// |   bb   |    2      | TimeLow[16:23]                 | Data1[16:23]    |
// |   cc   |    1      | TimeLow[8:15]                  | Data1[8:15]     |
// |   dd   |    0      | TimeLow[0:7]                   | Data1[0:7]      |
// |   ee   |    5      | TimeMid[8:15]                  | Data2[8:15]     |
// |   ff   |    4      | TimeMid[0:7]                   | Data2[0:7]      |
// |   gg   |    7      | TimeHigh And Version[8:15]     | Data3[8:15]     |
// |   hh   |    6      | TimeHigh And Version[0:7]      | Data3[0:7]      |
// |   ii   |    8      | ClockSeqHigh And Reserved[0:7] | Data4[0:7]      |
// |   jj   |    9      | ClockSeqLow[0:7]               | Data4[8:15]     |
// |   kk   |   10      | Node[0:7]                      | Data4[16:23]    |
// |   ll   |   11      | Node[8:15]                     | Data4[24:31]    |
// |   mm   |   12      | Node[16:23]                    | Data4[32:39]    |
// |   nn   |   13      | Node[24:31]                    | Data4[40:47]    |
// |   oo   |   14      | Node[32:39]                    | Data4[48:55]    |
// |   pp   |   15      | Node[40:47]                    | Data4[56:63]    |
// +--------+-----------+--------------------------------+-----------------+
//
// First 4 blocks are in little endian.
fbl::Vector<char> ToStr(const efi_guid& g) {
  fbl::Vector<char> res;
  res.resize(kEfiGuidStrLen + 1);

  cpp20::span<const uint8_t> buf(reinterpret_cast<const uint8_t*>(&g), sizeof(g));

  snprintf(res.data(), res.size(),
           "%02x%02x%02x%02x-"          // aabbccdd-
           "%02x%02x-"                  // eeff-
           "%02x%02x-"                  // gghh-
           "%02x%02x-"                  // iijj-
           "%02x%02x%02x%02x%02x%02x",  // kkllmmnnoopp
           buf[3],                      // |   aa   |    3      |
           buf[2],                      // |   bb   |    2      |
           buf[1],                      // |   cc   |    1      |
           buf[0],                      // |   dd   |    0      |
           buf[5],                      // |   ee   |    5      |
           buf[4],                      // |   ff   |    4      |
           buf[7],                      // |   gg   |    7      |
           buf[6],                      // |   hh   |    6      |
           buf[8],                      // |   ii   |    8      |
           buf[9],                      // |   jj   |    9      |
           buf[10],                     // |   kk   |   10      |
           buf[11],                     // |   ll   |   11      |
           buf[12],                     // |   mm   |   12      |
           buf[13],                     // |   nn   |   13      |
           buf[14],                     // |   oo   |   14      |
           buf[15]);                    // |   pp   |   15      |

  return res;
}

fit::result<efi_status> Timer::SetTimer(efi_timer_delay type, zx::duration timeout) {
  if (type == TimerCancel) {
    return fit::error(EFI_INVALID_PARAMETER);
  }
  if (timeout == zx::duration::infinite()) {
    state_ = State::kInfinite;
    return fit::ok();
  }
  if (timeout == zx::duration(0)) {
    state_ = State::kZero;
    return fit::ok();
  }

  state_ = State::kNormal;
  if (!timer_event_) {
    efi_status status =
        sys_->BootServices->CreateEvent(EVT_TIMER, 0, nullptr, nullptr, &timer_event_);
    if (status != EFI_SUCCESS) {
      return fit::error(status);
    }
  }

  // Timer ticks are in 100ns.
  efi_status res = sys_->BootServices->SetTimer(timer_event_, type, timeout.to_usecs() * 10);
  if (res == EFI_SUCCESS) {
    return fit::ok();
  }

  return fit::error(res);
}

fit::result<efi_status> Timer::Cancel() {
  if (!timer_event_) {
    return fit::ok();
  }

  efi_status res = sys_->BootServices->SetTimer(timer_event_, TimerCancel, 0);
  if (res == EFI_SUCCESS) {
    return fit::ok();
  }

  return fit::error(res);
}

Timer::Status Timer::CheckTimer() {
  if (state_ == State::kZero) {
    return Status::kReady;
  }
  if (state_ == State::kInfinite) {
    return Status::kWaiting;
  }
  if (!timer_event_) {
    return Status::kError;
  }

  efi_status res = sys_->BootServices->CheckEvent(timer_event_);
  switch (res) {
    case EFI_SUCCESS:
      return Status::kReady;
    case EFI_NOT_READY:
      return Status::kWaiting;
    default:
      return Status::kError;
  }
}

}  // namespace gigaboot
