// Copyright 2017 The Fuchsia Authors
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT

#include "zbi.h"

#include <lib/zbitl/view.h>
#include <lib/zbitl/vmo.h>
#include <zircon/boot/image.h>
#include <zircon/status.h>

#include "decompressor.h"
#include "util.h"

namespace {

constexpr const char kBootfsVmoName[] = "uncompressed-bootfs";

zx::vmo DecompressBootfs(const zx::debuglog& log, const zx::vmar& vmar_self, const zx::vmo& zbi_vmo,
                         uint64_t payload_offset, uint32_t payload_size,
                         uint32_t uncompressed_size) {
  zx::vmo bootfs_vmo;
  zx_status_t status = zx::vmo::create(uncompressed_size, 0, &bootfs_vmo);
  check(log, status, "cannot create BOOTFS VMO (%u bytes)", uncompressed_size);
  status = zbi_decompress(log, vmar_self, zbi_vmo, payload_offset, payload_size, bootfs_vmo, 0,
                          uncompressed_size);
  check(log, status, "failed to decompress BOOTFS");
  printl(log, "decompressed BOOTFS to VMO!\n");
  return bootfs_vmo;
}

zx::vmo ExtractBootfs(const zx::debuglog& log, const zx::vmar& vmar_self, const zx::vmo& zbi_vmo,
                      uint64_t payload_offset, uint32_t payload_size) {
  zx::vmo bootfs_vmo;

  if (payload_offset % ZX_PAGE_SIZE == 0) {
    zx_status_t status =
        zbi_vmo.create_child(ZX_VMO_CHILD_COPY_ON_WRITE, payload_offset, payload_size, &bootfs_vmo);
    check(log, status, "zx_vmo_create_child failed for BOOTFS");
    printl(log, "cloned uncompressed BOOTFS to VMO!\n");
    return bootfs_vmo;
  }

  // The data is not aligned, so it must be copied into a new VMO.
  zx_status_t status = zx::vmo::create(payload_size, 0, &bootfs_vmo);
  check(log, status, "cannot create BOOTFS VMO (%u bytes)", payload_size);
  uintptr_t bootfs_payload;
  status = vmar_self.map(0, bootfs_vmo, 0, payload_size, ZX_VM_PERM_READ | ZX_VM_PERM_WRITE,
                         &bootfs_payload);
  check(log, status, "cannot map BOOTFS VMO (%u bytes)", payload_size);
  status = zbi_vmo.read(reinterpret_cast<void*>(bootfs_payload), payload_offset, payload_size);
  check(log, status, "cannot read BOOTFS into VMO (%u bytes)", payload_size);
  status = vmar_self.unmap(bootfs_payload, payload_size);
  check(log, status, "cannot unmap BOOTFS VMO (%u bytes)", payload_size);

  printl(log, "copied uncompressed BOOTFS to VMO!\n");
  return bootfs_vmo;
}

}  // namespace

zx::vmo GetBootfsFromZbi(const zx::debuglog& log, const zx::vmar& vmar_self,
                         const zx::vmo& zbi_vmo) {
  zx::vmo vmo;
  check(log, zbi_vmo.duplicate(ZX_RIGHT_SAME_RIGHTS, &vmo), "cannot duplicate ZBI VMO\n");
  zbitl::PermissiveView<zx::vmo> zbi(std::move(vmo));

  for (auto it = zbi.begin(); it != zbi.end(); ++it) {
    auto [header, payload] = *it;
    if (header->type == ZBI_TYPE_STORAGE_BOOTFS) {
      zx::vmo bootfs_vmo =
          (header->flags & ZBI_FLAG_STORAGE_COMPRESSED)
              ? DecompressBootfs(log, vmar_self, zbi_vmo, payload, header->length, header->extra)
              : ExtractBootfs(log, vmar_self, zbi_vmo, payload, header->length);
      bootfs_vmo.set_property(ZX_PROP_NAME, kBootfsVmoName, sizeof(kBootfsVmoName) - 1);

      // Signal that we've already processed this one.
      // GCC's -Wmissing-field-initializers is buggy: it should allow
      // designated initializers without all fields, but doesn't (in C++?).
      zbi_header_t discard{};
      discard.type = ZBI_TYPE_DISCARD;
      if (auto ok = it.Replace(discard); ok.is_error()) {
        check(log, ok.error_value(), "zx_vmo_write failed on ZBI VMO\n");
      }

      // Cancel error-checking since we're ending the iteration on purpose.
      zbi.ignore_error();
      return bootfs_vmo;
    }
  }

  if (auto check = zbi.take_error(); check.is_error()) {
    auto error = check.error_value();
    if (error.storage_error) {
      fail(log, "invalid ZBI: %.*s at offset %#x\n", static_cast<int>(error.zbi_error.size()),
           error.zbi_error.data(), error.item_offset);
    } else {
      fail(log, "invalid ZBI: %.*s at offset %#x: %s\n", static_cast<int>(error.zbi_error.size()),
           error.zbi_error.data(), error.item_offset, zx_status_get_string(*error.storage_error));
    }
  } else {
    fail(log, "no '/boot' bootfs in bootstrap message\n");
  }
}
