// Copyright 2021 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 "phys/kernel-package.h"

#include <lib/boot-options/boot-options.h>
#include <lib/boot-options/word-view.h>
#include <lib/memalloc/range.h>
#include <lib/zbitl/error-stdio.h>
#include <lib/zbitl/view.h>
#include <string.h>

#include <ktl/algorithm.h>
#include <ktl/move.h>
#include <ktl/optional.h>
#include <ktl/string_view.h>
#include <phys/main.h>
#include <phys/stdio.h>
#include <phys/symbolize.h>
#include <phys/zbitl-allocation.h>
#include <pretty/cpp/sizes.h>

#include <ktl/enforce.h>

namespace {

[[noreturn]] void BadZbi(KernelStorage::Zbi zbi, size_t count,
                         ktl::optional<KernelStorage::Zbi::Error> error) {
  printf("%s: Invalid ZBI of %zu bytes, %zu items: ", ProgramName(), zbi.size_bytes(), count);

  if (error) {
    zbitl::PrintViewError(*error);
    printf("\n");
  } else {
    printf("No STORAGE_KERNEL item found!\n");
  }

  for (auto [header, payload] : zbi) {
    ktl::string_view name = zbitl::TypeName(header->type);
    if (name.empty()) {
      name = "unknown!";
    }
    printf(
        "\
%s: Item @ %#08x size %#08x type %#08x (%.*s) extra %#08x flags %#08x\n",
        ProgramName(), static_cast<uint32_t>(payload.data() - zbi.storage().data()), header->length,
        header->type, static_cast<int>(name.size()), name.data(), header->extra, header->flags);
  }
  zbi.ignore_error();
  abort();
}

}  // namespace

void KernelStorage::Init(Zbi zbi) {
  zbi_ = ktl::move(zbi);
  item_ = zbi_.end();

  size_t count = 0;
  for (auto it = zbi_.begin(); it != zbi_.end(); ++it) {
    ++count;
    if (it->header->type == ZBI_TYPE_STORAGE_KERNEL) {
      item_ = it;
      break;
    }
  }

  if (auto result = zbi_.take_error(); result.is_error()) {
    BadZbi(zbi_, count, result.error_value());
  }

  if (item_ == zbi_.end()) {
    BadZbi(zbi_, count, ktl::nullopt);
  }

  fbl::AllocChecker ac;
  const uint32_t storage_size = zbitl::UncompressedLength(*item_->header);
  storage_ =
      Allocation::New(ac, memalloc::Type::kKernelStorage, storage_size, ZBI_BOOTFS_PAGE_SIZE);
  if (!ac.check()) {
    printf("%s: Cannot allocate %#x bytes for decompressed STORAGE_KERNEL item!\n", ProgramName(),
           storage_size);
    abort();
  }

  // This marks the interval from completing basic phys environment setup
  // (kPhysSetup) to when the ZBI has been decoded enough to start accessing
  // the real kernel payload (which is usually compressed).
  decompress_start_ts_ = arch::EarlyTicks::Get();

  if (auto result = zbi_.CopyStorageItem(data(), item_, ZbitlScratchAllocator); result.is_error()) {
    printf("%s: Cannot load STORAGE_KERNEL item (uncompressed size %#x): ", ProgramName(),
           storage_size);
    zbitl::PrintViewCopyError(result.error_value());
    abort();
  }

  // This marks just the decompression (or copying) time.
  decompress_end_ts_ = arch::EarlyTicks::Get();

  debugf("%s: STORAGE_KERNEL decompressed %s -> %s\n", ProgramName(),
         pretty::FormattedBytes(item_->header->length).c_str(),
         pretty::FormattedBytes(storage_size).c_str());

  if (auto result = BootfsReader::Create(data()); result.is_error()) {
    printf("%s: cannot open BOOTFS image from KERNEL_STORAGE item (%#zx bytes at %p): ",
           ProgramName(), data().size(), data().data());
    zbitl::PrintBootfsError(result.error_value());
    abort();
  } else {
    bootfs_reader_ = ktl::move(result).value();
  }
}

KernelStorage::Bootfs KernelStorage::GetKernelPackage() const {
  ktl::string_view package_name = gBootOptions->select.data();
  debugf("%s: Finding kernel package %.*s...\n", gSymbolize->name(),
         static_cast<int>(package_name.size()), package_name.data());
  auto result = root().subdir(package_name);
  if (result.is_error()) {
    printf("%s: Cannot read kernel package: ", gSymbolize->name());
    zbitl::PrintBootfsError(result.error_value());
    abort();
  }
  return ktl::move(result).value();
}
