// Copyright 2024 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 "gbl_efi_fastboot_protocol.h"

#include <zircon/assert.h>

#include <functional>
#include <span>
#include <string_view>

#include <phys/efi/main.h>

#include "utils.h"

#define GBL_EFI_FASTBOOT_PROTOCOL_GUID \
  {0xc67e48a0, 0x5eb8, 0x4127, {0xbe, 0x89, 0xdf, 0x2e, 0xd9, 0x3d, 0x8a, 0x9a}}

// Set within `LaunchGbl()`;
bool g_should_stop_in_fastboot = false;

namespace {
struct GblEfiFastbootProtocol {
  struct gbl_efi_fastboot_protocol protocol;
};

// Contains information such as variable name and value.
constexpr struct Variable {
  const char* var_name;
  // For now we only consider constant variable.
  const char* var_impl;

  /// Gets the name as a string_view.
  std::string_view name() const { return std::string_view(var_name); }

  /// Gets the value as a string_view.
  std::string_view impl() const { return std::string_view(var_impl); }
} kVariables[] = {
    {"hw-revision", BOARD_NAME},
};

/// Gets the list of variables
std::span<const Variable> variables() { return std::span<const Variable>(kVariables); }

EFIAPI efi_status GetVar(struct gbl_efi_fastboot_protocol* self, const char* const* args,
                         size_t num_args, uint8_t* buf, size_t* bufsize) {
  const std::span<const char* const> args_span{args, num_args};
  if (args_span.empty() || !bufsize) {
    return EFI_INVALID_PARAMETER;
  }

  std::span<uint8_t> out{buf, *bufsize};
  for (size_t i = 0; i < variables().size(); i++) {
    const Variable& var = variables()[i];
    if (std::string_view(args_span[0]) != var.name()) {
      continue;
    }

    if (out.size() < var.impl().size() + 1) {
      return EFI_BUFFER_TOO_SMALL;
    }
    memcpy(out.data(), var.impl().data(), var.impl().size());
    *bufsize = var.impl().size();
    out.data()[*bufsize] = 0;
    return EFI_SUCCESS;
  }
  return EFI_NOT_FOUND;
}

EFIAPI efi_status GetVarAll(struct gbl_efi_fastboot_protocol* self, void* ctx,
                            get_var_callback cb) {
  for (size_t i = 0; i < variables().size(); i++) {
    std::array args{variables()[i].name().data()};
    cb(ctx, args.data(), args.size(), variables()[i].impl().data());
  }
  return EFI_SUCCESS;
}

EFIAPI efi_status RunOemFunction(struct gbl_efi_fastboot_protocol* self, const char* cmd,
                                 size_t len, uint8_t* download_buffer, size_t download_data_size,
                                 fastboot_message_sender sender, void* ctx) {
  return EFI_UNSUPPORTED;
}

EFIAPI efi_status GetStaged(struct gbl_efi_fastboot_protocol* self, uint8_t* out, size_t* out_size,
                            size_t* out_remain) {
  return EFI_UNSUPPORTED;
}

EFIAPI efi_status GetPolicy(struct gbl_efi_fastboot_protocol* self,
                            gbl_efi_fastboot_policy* policy) {
  return EFI_UNSUPPORTED;
}

EFIAPI efi_status SetLock(struct gbl_efi_fastboot_protocol* self, uint64_t lock_state) {
  return EFI_UNSUPPORTED;
}

EFIAPI efi_status ClearLock(struct gbl_efi_fastboot_protocol* self, uint64_t lock_state) {
  return EFI_UNSUPPORTED;
}

EFIAPI efi_status StartLocal(struct gbl_efi_fastboot_protocol* self, void** ctx) {
  return EFI_UNSUPPORTED;
}

EFIAPI efi_status UpdateLocal(struct gbl_efi_fastboot_protocol* self, void* ctx, uint8_t* buf,
                              size_t* size) {
  return EFI_UNSUPPORTED;
}

EFIAPI efi_status CloseLocal(struct gbl_efi_fastboot_protocol* self, void* ctx) {
  return EFI_UNSUPPORTED;
}

EFIAPI efi_status GetPartitionPermissions(struct gbl_efi_fastboot_protocol* self,
                                          const uint8_t* part_name, size_t part_name_len,
                                          uint64_t* permissions) {
  return EFI_UNSUPPORTED;
}

EFIAPI efi_status WipeUserData(struct gbl_efi_fastboot_protocol* self) { return EFI_UNSUPPORTED; }

EFIAPI bool ShouldStopInFastboot(struct gbl_efi_fastboot_protocol* self) {
  return g_should_stop_in_fastboot;
}

GblEfiFastbootProtocol protocol = {.protocol = {
                                       .version = 0x01,
                                       .get_var = GetVar,
                                       .get_var_all = GetVarAll,
                                       .run_oem_function = RunOemFunction,
                                       .get_staged = GetStaged,
                                       .get_policy = GetPolicy,
                                       .set_lock = SetLock,
                                       .clear_lock = ClearLock,
                                       .start_local_session = StartLocal,
                                       .update_local_session = UpdateLocal,
                                       .close_local_session = CloseLocal,
                                       .get_partition_permissions = GetPartitionPermissions,
                                       .wipe_user_data = WipeUserData,
                                       .should_stop_in_fastboot = ShouldStopInFastboot,
                                   }};

efi_guid guid = GBL_EFI_FASTBOOT_PROTOCOL_GUID;

}  // namespace

namespace gigaboot {
efi_status InstallGblEfiFastbootProtocol() {
  efi_handle out_handle = NULL;
  return gEfiSystemTable->BootServices->InstallMultipleProtocolInterfaces(&out_handle, &guid,
                                                                          &protocol.protocol, NULL);
}
}  // namespace gigaboot
