// Copyright 2021 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef SRC_LIB_ZBITL_TESTS_BOOTFS_TESTS_H_
#define SRC_LIB_ZBITL_TESTS_BOOTFS_TESTS_H_

#include <lib/zbitl/items/bootfs.h>
#include <lib/zbitl/view.h>

#include <iterator>

#include <fbl/unique_fd.h>
#include <gtest/gtest.h>

#include "array-tests.h"
#include "fd-tests.h"
#include "src/lib/files/scoped_temp_dir.h"
#include "tests.h"

template <typename TestTraits>
void CreateBootfs(typename TestTraits::Context& context,
                  zbitl::Bootfs<typename TestTraits::storage_type>& bootfs) {
  using Storage = typename TestTraits::storage_type;

  files::ScopedTempDir dir;
  fbl::unique_fd fd;
  size_t size = 0;
  ASSERT_NO_FATAL_FAILURE(OpenTestDataZbi(TestDataZbiType::kBootfs, dir.path(), &fd, &size));

  // Read the ZBI containing the BOOTFS into memory.
  typename FblByteArrayTestTraits::Context zbi_context;
  ASSERT_NO_FATAL_FAILURE(FblByteArrayTestTraits::Create(std::move(fd), size, &zbi_context));
  zbitl::View view(zbi_context.TakeStorage());

  auto it = view.begin();
  ASSERT_EQ(std::next(it), view.end()) << "expected a single BOOTFS item";
  ASSERT_EQ(uint32_t{ZBI_TYPE_STORAGE_BOOTFS}, it->header->type);

  // Ultimately we want to create an object of storage_type containing the
  // BOOTFS - and the preferred choice of test traits for creating storage
  // objects with prescribed contents is to use a fbl::unique_fd. Accordingly,
  // we decompress the BOOTFS into this form.
  const uint32_t bootfs_size = zbitl::UncompressedLength(*it->header);
  typename FdTestTraits::Context decompressed_context;
  ASSERT_NO_FATAL_FAILURE(FdTestTraits::Create(bootfs_size, &decompressed_context));

  fbl::unique_fd bootfs_fd = decompressed_context.TakeStorage();
  {
    auto result = view.CopyStorageItem(bootfs_fd, it);
    ASSERT_FALSE(result.is_error()) << ViewCopyErrorString(result.error_value());
  }

  ASSERT_NO_FATAL_FAILURE(TestTraits::Create(std::move(bootfs_fd), bootfs_size, &context));

  {
    auto result = zbitl::Bootfs<Storage>::Create(context.TakeStorage());
    ASSERT_FALSE(result.is_error()) << BootfsErrorString(result.error_value());
    bootfs = std::move(result.value());
  }

  {
    auto result = view.take_error();
    EXPECT_FALSE(result.is_error()) << ViewErrorString(result.error_value());
  }
}

template <typename BootfsView>
void TestFind(BootfsView& bootfs, std::initializer_list<std::string_view> path_parts,
              typename BootfsView::iterator expected_it) {
  auto match = bootfs.find(path_parts);
  auto result = bootfs.take_error();
  ASSERT_FALSE(result.is_error()) << BootfsErrorString(result.error_value());
  EXPECT_EQ(expected_it, match);
}

template <typename TestTraits>
void TestBootfsIteration() {
  using namespace std::string_view_literals;
  using Storage = typename TestTraits::storage_type;

  typename TestTraits::Context context;
  zbitl::Bootfs<Storage> reader;
  ASSERT_NO_FATAL_FAILURE(CreateBootfs<TestTraits>(context, reader));

  auto bootfs = reader.root();
  uint32_t idx = 0;
  for (auto it = bootfs.begin(); it != bootfs.end(); ++it) {
    Bytes contents;
    ASSERT_NO_FATAL_FAILURE(TestTraits::Read(reader.storage(), it->data, it->size, &contents));

    ASSERT_NO_FATAL_FAILURE(TestFind(bootfs, {it->name}, it));
    ASSERT_NO_FATAL_FAILURE(TestFind(bootfs, {it->name}, it));
    switch (idx) {
      case 0:
        EXPECT_EQ(it->name, "A.txt"sv);
        EXPECT_EQ(contents,
                  "Four score and seven years ago our fathers brought forth on this "
                  "continent, a new nation, conceived in Liberty, and dedicated to the "
                  "proposition that all men are created equal.");
        break;
      case 1:
        EXPECT_EQ(it->name, "nested/B.txt"sv);
        ASSERT_NO_FATAL_FAILURE(TestFind(bootfs, {"nested"sv, "B.txt"sv}, it));
        EXPECT_EQ(contents,
                  "Now we are engaged in a great civil war, testing whether that nation, "
                  "or any nation so conceived and so dedicated, can long endure.");
        break;
      case 2:
        EXPECT_EQ(it->name, "nested/again/C.txt"sv);
        ASSERT_NO_FATAL_FAILURE(TestFind(bootfs, {"nested/again"sv, "C.txt"sv}, it));
        ASSERT_NO_FATAL_FAILURE(TestFind(bootfs, {"nested"sv, "again/C.txt"sv}, it));
        ASSERT_NO_FATAL_FAILURE(TestFind(bootfs, {"nested"sv, "again"sv, "C.txt"sv}, it));
        EXPECT_EQ(contents, "We are met on a great battle-field of that war.");
        break;
      default:
        __UNREACHABLE;
    }

    ++idx;
  }
  EXPECT_EQ(3u, idx) << "we expect three files in the BOOTFS";

  {
    auto result = bootfs.take_error();
    EXPECT_FALSE(result.is_error()) << BootfsErrorString(result.error_value());
  }
}

template <typename TestTraits>
void TestBootfsSubdirectory() {
  using namespace std::string_view_literals;
  using Storage = typename TestTraits::storage_type;

  typename TestTraits::Context context;
  zbitl::Bootfs<Storage> reader;
  ASSERT_NO_FATAL_FAILURE(CreateBootfs<TestTraits>(context, reader));

  zbitl::BootfsView<Storage> root = reader.root();

  {
    auto result = root.subdir("nonexistent/directory"sv);
    ASSERT_TRUE(result.is_error());
    EXPECT_EQ("unknown directory"sv, result.error_value().reason);
  }

  constexpr std::string_view kErrFileNotDir = "provided name is for a file, not a directory";
  {
    auto result = root.subdir("A.txt"sv);
    ASSERT_TRUE(result.is_error());
    EXPECT_EQ(kErrFileNotDir, result.error_value().reason);
  }
  {
    auto result = root.subdir("nested/B.txt"sv);
    ASSERT_TRUE(result.is_error());
    EXPECT_EQ(kErrFileNotDir, result.error_value().reason);
  }
  {
    auto result = root.subdir("nested/again/C.txt"sv);
    ASSERT_TRUE(result.is_error());
    EXPECT_EQ(kErrFileNotDir, result.error_value().reason);
  }

  {
    auto result = root.subdir("nested"sv);
    ASSERT_FALSE(result.is_error()) << BootfsErrorString(result.error_value());
    auto subdir = std::move(result).value();

    EXPECT_EQ("nested"sv, subdir.directory());

    uint32_t idx = 0u;
    for (auto it = subdir.begin(); it != subdir.end(); ++it) {
      ASSERT_NO_FATAL_FAILURE(TestFind(subdir, {it->name}, it));
      switch (idx++) {
        case 0u:
          EXPECT_EQ(it->name, "B.txt"sv);
          break;
        case 1u:
          EXPECT_EQ(it->name, "again/C.txt"sv);
          ASSERT_NO_FATAL_FAILURE(TestFind(subdir, {"again"sv, "C.txt"sv}, it));
          break;
      }
    }
    EXPECT_EQ(2u, idx) << "expected two files in the BOOTFS subdirectory";

    auto take_result = subdir.take_error();
    EXPECT_FALSE(take_result.is_error()) << BootfsErrorString(take_result.error_value());
  }

  {
    auto result = root.subdir("nested/again"sv);
    ASSERT_FALSE(result.is_error()) << BootfsErrorString(result.error_value());
    auto subdir = std::move(result).value();

    EXPECT_EQ("nested/again"sv, subdir.directory());

    uint32_t idx = 0u;
    for (auto it = subdir.begin(); it != subdir.end(); ++it) {
      ASSERT_NO_FATAL_FAILURE(TestFind(subdir, {it->name}, it));
      switch (idx++) {
        case 0u:
          EXPECT_EQ(it->name, "C.txt"sv);
          break;
      }
    }
    EXPECT_EQ(1u, idx) << "expected one files in the BOOTFS subdirectory";

    auto take_result = subdir.take_error();
    EXPECT_FALSE(take_result.is_error()) << BootfsErrorString(take_result.error_value());
  }
}

#endif  // SRC_LIB_ZBITL_TESTS_BOOTFS_TESTS_H_
