/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use, copy,
 * modify, merge, publish, distribute, sublicense, and/or sell copies
 * of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#include <efi.h>
#include <efilib.h>

#include <libavb_ab/libavb_ab.h>

#include "uefi_avb_boot.h"
#include "uefi_avb_ops.h"

EFI_STATUS EFIAPI efi_main(EFI_HANDLE ImageHandle,
                           EFI_SYSTEM_TABLE* SystemTable) {
  AvbOps* ops;
  AvbABFlowResult ab_result;
  AvbSlotVerifyData* slot_data;
  UEFIAvbBootKernelResult boot_result;
  const char* requested_partitions[] = {"boot", NULL};
  bool unlocked = true;
  char* additional_cmdline = NULL;
  AvbSlotVerifyFlags flags;

  InitializeLib(ImageHandle, SystemTable);

  avb_printv("UEFI AVB-based bootloader using libavb version ",
             avb_version_string(),
             "\n",
             NULL);

  ops = uefi_avb_ops_new(ImageHandle);
  if (ops == NULL) {
    avb_fatal("Error allocating AvbOps.\n");
  }

  if (ops->read_is_device_unlocked(ops, &unlocked) != AVB_IO_RESULT_OK) {
    avb_fatal("Error determining whether device is unlocked.\n");
  }
  avb_printv("read_is_device_unlocked() ops returned that device is ",
             unlocked ? "UNLOCKED" : "LOCKED",
             "\n",
             NULL);

  flags = AVB_SLOT_VERIFY_FLAGS_NONE;
  if (unlocked) {
    flags |= AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR;
  }

  ab_result = avb_ab_flow(ops->ab_ops,
                          requested_partitions,
                          flags,
                          AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
                          &slot_data);
  avb_printv("avb_ab_flow() returned ",
             avb_ab_flow_result_to_string(ab_result),
             "\n",
             NULL);
  switch (ab_result) {
    case AVB_AB_FLOW_RESULT_OK:
    case AVB_AB_FLOW_RESULT_OK_WITH_VERIFICATION_ERROR:
      avb_printv("slot_suffix:    ", slot_data->ab_suffix, "\n", NULL);
      avb_printv("cmdline:        ", slot_data->cmdline, "\n", NULL);
      avb_printv(
          "release string: ",
          (const char*)((((AvbVBMetaImageHeader*)(slot_data->vbmeta_images[0]
                                                      .vbmeta_data)))
                            ->release_string),
          "\n",
          NULL);
      /* Pass 'skip_initramfs' since we're not booting into recovery
       * mode. Also pass the selected slot in androidboot.slot and the
       * suffix in androidboot.slot_suffix.
       */
      additional_cmdline = avb_strdupv("skip_initramfs ",
                                       "androidboot.slot=",
                                       slot_data->ab_suffix + 1,
                                       " ",
                                       "androidboot.slot_suffix=",
                                       slot_data->ab_suffix,
                                       NULL);
      if (additional_cmdline == NULL) {
        avb_fatal("Error allocating additional_cmdline.\n");
      }
      boot_result =
          uefi_avb_boot_kernel(ImageHandle, slot_data, additional_cmdline);
      avb_fatalv("uefi_avb_boot_kernel() failed with error ",
                 uefi_avb_boot_kernel_result_to_string(boot_result),
                 "\n",
                 NULL);
      avb_slot_verify_data_free(slot_data);
      avb_free(additional_cmdline);
      break;
    case AVB_AB_FLOW_RESULT_ERROR_OOM:
      avb_fatal("OOM error while doing A/B select flow.\n");
      break;
    case AVB_AB_FLOW_RESULT_ERROR_IO:
      avb_fatal("I/O error while doing A/B select flow.\n");
      break;
    case AVB_AB_FLOW_RESULT_ERROR_NO_BOOTABLE_SLOTS:
      avb_fatal("No bootable slots - enter repair mode\n");
      break;
    case AVB_AB_FLOW_RESULT_ERROR_INVALID_ARGUMENT:
      avb_fatal("Invalid arguments passed\n");
      break;
  }
  uefi_avb_ops_free(ops);

  return EFI_SUCCESS;
}
