// Copyright 2022 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 <lib/arch/zbi-boot.h>
#include <lib/boot-shim/boot-shim.h>
#include <lib/boot-shim/debugdata.h>
#include <lib/zbitl/error-stdio.h>
#include <lib/zbitl/items/debugdata.h>
#include <stdio.h>
#include <zircon/assert.h>

#include <ktl/iterator.h>
#include <ktl/string_view.h>
#include <phys/symbolize.h>

#include "turducken.h"

#include <ktl/enforce.h>

using Shim = boot_shim::BootShim<boot_shim::DebugdataItem>;

const char* kTestName = "debugdata-boot-shim-test";

// When given this option...
constexpr ktl::string_view kPublishOption = "debugdata.publish";

// ...emit this ZBI_TYPE_DEBUGDATA contents to the next iteration.
// Without the publish option, check that such an item was received.
constexpr ktl::string_view kSinkName = "test-sink";
constexpr ktl::string_view kVmoName = "test-debugdata";
constexpr ktl::string_view kContents = "test debugdata contents";
constexpr ktl::string_view kLog = "test log text\nsecond line of log";

int TurduckenTest::Main(Zbi::iterator kernel_item) {
  Shim shim(gSymbolize->name());
  shim.set_build_id(gSymbolize->build_id());

  LogBootZbiItems(kernel_item);

  // First time through, publish the debugdata.
  if (Option(kPublishOption)) {
    RemoveOption(kPublishOption);

    auto& debugdata = shim.Get<boot_shim::DebugdataItem>();
    debugdata.Init(kSinkName, kVmoName);
    debugdata.set_content_size(kContents.size());
    debugdata.set_log(kLog);
    printf("%s: Initialized item of %zu bytes\n", gSymbolize->name(), debugdata.size_bytes());

    // Pass along the original items after the embedded ZBI, plus the new
    // debugdata item.
    printf("%s: Loading embedded ZBI with %zu bytes extra capacity...\n", gSymbolize->name(),
           shim.size_bytes());
    Load(kernel_item, ktl::next(kernel_item), boot_zbi().end(),
         static_cast<uint32_t>(shim.size_bytes()));

    printf("%s: Adding ZBI_TYPE_DEBUGDATA item...\n", gSymbolize->name());
    Shim::DataZbi zbi(loaded_zbi());
    if (auto result = shim.AppendItems(zbi); result.is_error()) {
      printf("%s: shim.AppendItems failed: ", gSymbolize->name());
      zbitl::PrintViewError(result.error_value());
      return -1;
    }
    ZX_ASSERT(zbi.take_error().is_ok());

    kContents.copy(reinterpret_cast<char*>(debugdata.contents().data()),
                   debugdata.contents().size());

    Boot();
  }

  // Second time through, check the data from last time.
  printf("%s: checking ZBI_TYPE_DEBUGDATA item...\n", gSymbolize->name());

  ktl::optional<zbitl::Debugdata> debugdata;
  for (auto [header, payload] : boot_zbi()) {
    if (header->type == ZBI_TYPE_DEBUGDATA) {
      ZX_ASSERT_MSG(!debugdata, "hit second ZBI_TYPE_DEBUGDATA item");
      debugdata.emplace();
      auto result = debugdata->Init(payload);
      ZX_ASSERT_MSG(result.is_ok(), "%.*s", static_cast<int>(result.error_value().size()),
                    result.error_value().data());
    }
  }
  if (auto result = boot_zbi().take_error(); result.is_error()) {
    printf("%s: ZBI iteration error: ", gSymbolize->name());
    zbitl::PrintViewError(result.error_value());
    return -1;
  }
  ZX_ASSERT_MSG(debugdata, "no ZBI_TYPE_DEBUGDATA item found");

  ZX_ASSERT(debugdata->sink_name() == kSinkName);
  ZX_ASSERT(debugdata->vmo_name() == kVmoName);
  ZX_ASSERT(debugdata->log() == kLog);
  const ktl::string_view contents{
      reinterpret_cast<const char*>(debugdata->contents().data()),
      debugdata->contents().size(),
  };
  ZX_ASSERT(contents == kContents);

  // If there's an embedded ZBI, boot it as is so it can start up and see that
  // same ZBI_TYPE_DEBUGDATA item that we just checked.
  if (kernel_item != boot_zbi().end()) {
    printf("%s: chain-loading next kernel...\n", gSymbolize->name());
    Load(kernel_item, ktl::next(kernel_item), boot_zbi().end());
    Boot();
  }

  // If nothing else is embedded, the test is done.
  return 0;
}
