// Copyright 2020 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/unittest/unittest.h>
#include <lib/zbitl/view.h>

#include <ktl/span.h>

#include "tests.h"

// zbitl is primarily tested by its host/userland unit tests.
// This serves to test some basic cases in the kernel and phys
// environments specifically, mostly just to make sure it compiles.

#define ASSERT_IS_OK(result) ASSERT_TRUE(result.is_ok())

namespace {

// `zbi --output=$OUTPUT_ZBI; hexdump -v -e '1/1 "\\x%02x"' $OUTPUT_ZBI`.
alignas(ZBI_ALIGNMENT) constexpr char kEmptyZbi[] =
    "\x42\x4f\x4f\x54\x00\x00\x00\x00\xe6\xf7\x8c\x86\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00"
    "\x00\x29\x17\x78\xb5\xd6\xe8\x87\x4a";

// ```
// zbi --output=$OUTPUT_ZBI --type CMDLINE --entry "hello world"
// hexdump -v -e '1/1 "\\x%02x"' $OUTPUT_ZBI
// ```
alignas(ZBI_ALIGNMENT) constexpr char kSimpleZbi[] =
    "\x42\x4f\x4f\x54\x30\x00\x00\x00\xe6\xf7\x8c\x86\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00"
    "\x00\x29\x17\x78\xb5\xd6\xe8\x87\x4a\x43\x4d\x44\x4c\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00"
    "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x29\x17\x78\xb5\x77\xa5\x78\x81\x68\x65\x6c\x6c\x6f"
    "\x20\x77\x6f\x72\x6c\x64\x00\x00\x00\x00\x00";

// The above, but with a payload byte changed.
alignas(ZBI_ALIGNMENT) constexpr char kBadCrcZbi[] =
    "\x42\x4f\x4f\x54\x30\x00\x00\x00\xe6\xf7\x8c\x86\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00"
    "\x00\x29\x17\x78\xb5\xd6\xe8\x87\x4a\x43\x4d\x44\x4c\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00"
    "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x29\x17\x78\xb5\x77\xa5\x78\x81\x00\x65\x6c\x6c\x6f"
    "\x20\x77\x6f\x72\x6c\x64\x00\x00\x00\x00\x00";

constexpr char kHelloWorld[] = "hello world";

bool EmptyZbiTest() {
  BEGIN_TEST;

  zbitl::View zbi(ktl::span<const char>{kEmptyZbi, sizeof(kEmptyZbi)});

  ASSERT_IS_OK(zbi.container_header());

  for (auto [header, payload] : zbi) {
    EXPECT_EQ(header->type, header->type);
    EXPECT_TRUE(false, "should not be reached");
  }

  ASSERT_IS_OK(zbi.take_error());

  END_TEST;
}

bool SimpleZbiTest() {
  BEGIN_TEST;

  zbitl::View zbi(ktl::span<const char>{kSimpleZbi, sizeof(kSimpleZbi)});

  ASSERT_IS_OK(zbi.container_header());

  size_t num_items = 0;
  for (auto [header, payload] : zbi) {
    EXPECT_EQ(static_cast<uint32_t>(ZBI_TYPE_CMDLINE), header->type);
    switch (num_items++) {
      case 0:
        ASSERT_EQ(sizeof(kHelloWorld), payload.size());
        EXPECT_EQ(0, memcmp(kHelloWorld, payload.data(), payload.size()));
        break;
    }
    EXPECT_TRUE(header->flags & ZBI_FLAG_VERSION);
  }
  EXPECT_EQ(1u, num_items);

  ASSERT_IS_OK(zbi.take_error());

  END_TEST;
}

bool BadCrcZbiTest() {
  BEGIN_TEST;

  zbitl::View<ktl::span<const char>> zbi({kBadCrcZbi, sizeof(kBadCrcZbi)});

  ASSERT_IS_OK(zbi.container_header());

  for (auto it = zbi.begin(); it != zbi.end(); ++it) {
    auto result = zbi.CheckCrc32(it);
    ASSERT_IS_OK(result);
    EXPECT_FALSE(result.value());
  }

  ASSERT_IS_OK(zbi.take_error());

  END_TEST;
}

bool MutationTest() {
  BEGIN_TEST;

  alignas(ZBI_ALIGNMENT) char contents[sizeof(kSimpleZbi)];
  memcpy(contents, kSimpleZbi, sizeof(contents));

  // Storage type is mutable.
  zbitl::View zbi(ktl::span<char>{contents, sizeof(contents)});

  ASSERT_IS_OK(zbi.container_header());

  size_t num_items = 0;
  for (auto it = zbi.begin(); it != zbi.end(); ++it) {
    auto [header, payload] = *it;
    EXPECT_EQ(static_cast<uint32_t>(ZBI_TYPE_CMDLINE), header->type);
    switch (num_items++) {
      case 0:
        ASSERT_EQ(sizeof(kHelloWorld), payload.size());
        EXPECT_EQ(0, memcmp(kHelloWorld, payload.data(), payload.size()));
        // 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;
        ASSERT_TRUE(zbi.EditHeader(it, discard).is_ok());
        break;
    }
    EXPECT_TRUE(header->flags & ZBI_FLAG_VERSION);
  }
  EXPECT_EQ(1u, num_items);

  num_items = 0;
  for (auto [header, payload] : zbi) {
    EXPECT_EQ(static_cast<uint32_t>(ZBI_TYPE_DISCARD), header->type);
    switch (num_items++) {
      case 0:
        ASSERT_EQ(sizeof(kHelloWorld), payload.size());
        EXPECT_EQ(0, memcmp(kHelloWorld, payload.data(), payload.size()));
        break;
    }
    EXPECT_TRUE(header->flags & ZBI_FLAG_VERSION);
  }
  EXPECT_EQ(1u, num_items);

  ASSERT_IS_OK(zbi.take_error());

  END_TEST;
}

}  // namespace

UNITTEST_START_TESTCASE(zbitl_tests)
UNITTEST("empty", EmptyZbiTest)
UNITTEST("simple", SimpleZbiTest)
UNITTEST("bad CRC", BadCrcZbiTest)
UNITTEST("mutation", MutationTest)
UNITTEST_END_TESTCASE(zbitl_tests, "zbitl", "Tests of ZBI template library")
