// Copyright 2019 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.

#include <lib/ftl/ndm-driver.h>
#include <string.h>

#include <optional>
#include <vector>

#include <gtest/gtest.h>

#include "ftl.h"
#include "ndm/ndmp.h"

namespace {

constexpr uint32_t kNumBlocks = 30;
constexpr uint32_t kPagesPerBlock = 16;
constexpr uint32_t kPageSize = 4096;
constexpr uint32_t kOobSize = 16;
constexpr uint32_t kBlockSize = kPageSize * kPagesPerBlock;

constexpr uint32_t kControlPage0 = (kNumBlocks - 1) * kPagesPerBlock;
constexpr uint32_t kControlPage1 = (kNumBlocks - 2) * kPagesPerBlock;

constexpr ftl::VolumeOptions kDefaultOptions = {kNumBlocks, 2, kBlockSize, kPageSize, kOobSize, 0};

class NdmRamDriver final : public ftl::NdmBaseDriver {
 public:
  NdmRamDriver(const ftl::VolumeOptions options = kDefaultOptions,
               FtlLogger logger = ftl::DefaultLogger())
      : NdmBaseDriver(logger), options_(options) {}

  const uint8_t* data(uint32_t page_num) const { return &volume_[page_num * kPageSize]; }
  NDM ndm() { return GetNdmForTest(); }
  void format_using_v2(bool value) { format_using_v2_ = value; }

  // Goes through the normal logic to create a volume with user data info.
  const char* CreateVolume() { return CreateNdmVolume(nullptr, options_, true); }

  // NdmDriver interface:
  const char* Init() final;
  const char* Attach(const ftl::Volume* ftl_volume) final;
  bool Detach() final;
  int NandRead(uint32_t start_page, uint32_t page_count, void* page_buffer, void* oob_buffer) final;
  int NandWrite(uint32_t start_page, uint32_t page_count, const void* page_buffer,
                const void* oob_buffer) final;
  int NandErase(uint32_t page_num) final;
  int IsBadBlock(uint32_t page_num) final { return ftl::kFalse; }
  bool IsEmptyPage(uint32_t page_num, const uint8_t* data, const uint8_t* spare) final {
    return IsEmptyPageImpl(data, kPageSize, spare, kOobSize);
  }
  uint32_t PageSize() final { return kPageSize; }
  uint8_t SpareSize() final { return kOobSize; }

 private:
  std::vector<uint8_t> volume_;
  ftl::VolumeOptions options_;
  bool format_using_v2_ = true;
};

const char* NdmRamDriver::Init() {
  size_t volume_size = (kPageSize + kOobSize) * kPagesPerBlock * kNumBlocks;
  volume_.resize(volume_size);
  memset(volume_.data(), 0xff, volume_size);
  return nullptr;
}

const char* NdmRamDriver::Attach(const ftl::Volume* ftl_volume) {
  if (!GetNdmForTest()) {
    IsNdmDataPresent(options_, format_using_v2_);
  }
  return GetNdmForTest() ? nullptr : "Failed to add device";
}

bool NdmRamDriver::Detach() { return RemoveNdmVolume(); }

int NdmRamDriver::NandRead(uint32_t start_page, uint32_t page_count, void* page_buffer,
                           void* oob_buffer) {
  uint8_t* data = reinterpret_cast<uint8_t*>(page_buffer);
  uint8_t* spare = reinterpret_cast<uint8_t*>(oob_buffer);

  if (data) {
    memcpy(data, &volume_[start_page * kPageSize], page_count * kPageSize);
  }

  if (spare) {
    uint32_t oob_offset = kPagesPerBlock * kNumBlocks * kPageSize;
    memcpy(spare, &volume_[oob_offset + start_page * kOobSize], page_count * kOobSize);
  }
  return ftl::kNdmOk;
}

int NdmRamDriver::NandWrite(uint32_t start_page, uint32_t page_count, const void* page_buffer,
                            const void* oob_buffer) {
  const uint8_t* data = reinterpret_cast<const uint8_t*>(page_buffer);
  const uint8_t* spare = reinterpret_cast<const uint8_t*>(oob_buffer);
  ZX_ASSERT(data);
  ZX_ASSERT(spare);

  uint32_t oob_offset = kPagesPerBlock * kNumBlocks * kPageSize;
  memcpy(&volume_[start_page * kPageSize], data, page_count * kPageSize);
  memcpy(&volume_[oob_offset + start_page * kOobSize], spare, page_count * kOobSize);
  return ftl::kNdmOk;
}

int NdmRamDriver::NandErase(uint32_t page_num) {
  ZX_ASSERT(page_num % kPagesPerBlock == 0);

  uint32_t oob_offset = kPagesPerBlock * kNumBlocks * kPageSize;
  memset(&volume_[page_num * kPageSize], 0xFF, kBlockSize);
  memset(&volume_[oob_offset + page_num * kOobSize], 0xFF, kPagesPerBlock * kOobSize);

  return ftl::kNdmOk;
}

class NdmTest : public ::testing::Test {
 public:
  void SetUp() override {
    ASSERT_TRUE(ftl::InitModules());
    ASSERT_EQ(nullptr, ndm_driver_.Init());
    ASSERT_EQ(nullptr, ndm_driver_.Attach(nullptr));
  }

 protected:
  NdmRamDriver ndm_driver_;
};

struct HeaderV1 {
  uint16_t current_location;
  uint16_t last_location;
  int32_t sequence_num;
  uint32_t crc;
  int32_t num_blocks;
  int32_t block_size;
  int32_t control_block0;
  int32_t control_block1;
  int32_t free_virt_block;
  int32_t free_control_block;
  int32_t transfer_to_block;
};

struct HeaderV2 {
  uint16_t major_version;
  uint16_t minor_version;
  HeaderV1 v1;
};

class NdmTestOldFormat : public NdmTest {
 public:
  void SetUp() override {
    ASSERT_TRUE(ftl::InitModules());
    ASSERT_EQ(nullptr, ndm_driver_.Init());
    ndm_driver_.format_using_v2(false);
    ASSERT_EQ(nullptr, ndm_driver_.Attach(nullptr));
  }
};

TEST_F(NdmTestOldFormat, WritesVersion1) {
  auto header = reinterpret_cast<const HeaderV1*>(ndm_driver_.data(kControlPage0));
  EXPECT_EQ(1, header->current_location);
  EXPECT_EQ(1, header->last_location);
  EXPECT_EQ(0, header->sequence_num);
  EXPECT_EQ(kNumBlocks, static_cast<uint32_t>(header->num_blocks));
  EXPECT_EQ(kPageSize * kPagesPerBlock, static_cast<uint32_t>(header->block_size));
  EXPECT_EQ(kNumBlocks - 1, static_cast<uint32_t>(header->control_block0));
  EXPECT_EQ(kNumBlocks - 2, static_cast<uint32_t>(header->control_block1));
  EXPECT_EQ(kNumBlocks - 4, static_cast<uint32_t>(header->free_virt_block));
  EXPECT_EQ(kNumBlocks - 3, static_cast<uint32_t>(header->free_control_block));
  EXPECT_EQ(-1, header->transfer_to_block);
}

TEST_F(NdmTest, WritesVersion2) {
  auto header = reinterpret_cast<const HeaderV2*>(ndm_driver_.data(kControlPage0));
  EXPECT_EQ(2, header->major_version);
  EXPECT_EQ(0, header->minor_version);
  EXPECT_EQ(1, header->v1.current_location);
  EXPECT_EQ(1, header->v1.last_location);
  EXPECT_EQ(0, header->v1.sequence_num);
  EXPECT_EQ(kNumBlocks, static_cast<uint32_t>(header->v1.num_blocks));
  EXPECT_EQ(kPageSize * kPagesPerBlock, static_cast<uint32_t>(header->v1.block_size));
  EXPECT_EQ(kNumBlocks - 1, static_cast<uint32_t>(header->v1.control_block0));
  EXPECT_EQ(kNumBlocks - 2, static_cast<uint32_t>(header->v1.control_block1));
  EXPECT_EQ(kNumBlocks - 4, static_cast<uint32_t>(header->v1.free_virt_block));
  EXPECT_EQ(kNumBlocks - 3, static_cast<uint32_t>(header->v1.free_control_block));
  EXPECT_EQ(-1, header->v1.transfer_to_block);
}

TEST_F(NdmTest, OnlyOneControlBlock) {
  auto header = reinterpret_cast<const HeaderV1*>(ndm_driver_.data(kControlPage0 + 1));
  EXPECT_EQ(0xffff, header->current_location);

  header = reinterpret_cast<const HeaderV1*>(ndm_driver_.data(kControlPage1));
  EXPECT_EQ(0xffff, header->current_location);
}

TEST_F(NdmTestOldFormat, NoVersion2) {
  NDMPartition partition = {};
  partition.num_blocks = ndmGetNumVBlocks(ndm_driver_.ndm());
  ASSERT_EQ(0, ndmWritePartition(ndm_driver_.ndm(), &partition, 0, "foo"));

  EXPECT_NE(nullptr, ndmGetPartition(ndm_driver_.ndm(), 0));
  EXPECT_EQ(nullptr, ndmGetPartitionInfo(ndm_driver_.ndm()));
}

TEST_F(NdmTest, UsesVersion2) {
  NDMPartitionInfo partition = {};
  uint32_t partition_size = ndmGetNumVBlocks(ndm_driver_.ndm());
  partition.basic_data.num_blocks = partition_size;
  strcpy(partition.basic_data.name, "foo");
  ASSERT_EQ(0, ndmWritePartitionInfo(ndm_driver_.ndm(), &partition));

  EXPECT_NE(nullptr, ndmGetPartition(ndm_driver_.ndm(), 0));

  const NDMPartitionInfo* info = ndmGetPartitionInfo(ndm_driver_.ndm());
  ASSERT_NE(nullptr, info);
  EXPECT_EQ(0u, info->basic_data.first_block);
  EXPECT_EQ(partition_size, info->basic_data.num_blocks);
  EXPECT_EQ(0u, info->user_data.data_size);
  EXPECT_STREQ("foo", info->basic_data.name);
}

TEST_F(NdmTest, SavesVersion2) {
  NDMPartitionInfo partition = {};
  partition.basic_data.num_blocks = ndmGetNumVBlocks(ndm_driver_.ndm());
  ASSERT_EQ(0, ndmWritePartitionInfo(ndm_driver_.ndm(), &partition));
  ASSERT_EQ(0, ndmSavePartitionTable(ndm_driver_.ndm()));

  auto header = reinterpret_cast<const HeaderV2*>(ndm_driver_.data(kControlPage0 + 1));
  EXPECT_EQ(2, header->major_version);
  EXPECT_EQ(0, header->minor_version);
  EXPECT_EQ(1, header->v1.current_location);
  EXPECT_EQ(1, header->v1.last_location);
  EXPECT_EQ(1, header->v1.sequence_num);
  EXPECT_EQ(kNumBlocks, static_cast<uint32_t>(header->v1.num_blocks));
  EXPECT_EQ(kPageSize * kPagesPerBlock, static_cast<uint32_t>(header->v1.block_size));
  EXPECT_EQ(kNumBlocks - 1, static_cast<uint32_t>(header->v1.control_block0));
  EXPECT_EQ(kNumBlocks - 2, static_cast<uint32_t>(header->v1.control_block1));
  EXPECT_EQ(kNumBlocks - 4, static_cast<uint32_t>(header->v1.free_virt_block));
  EXPECT_EQ(kNumBlocks - 3, static_cast<uint32_t>(header->v1.free_control_block));
  EXPECT_EQ(-1, header->v1.transfer_to_block);
}

TEST_F(NdmTest, OnlyOneV2ControlBlock) {
  NDMPartitionInfo partition = {};
  partition.basic_data.num_blocks = ndmGetNumVBlocks(ndm_driver_.ndm());
  ASSERT_EQ(0, ndmWritePartitionInfo(ndm_driver_.ndm(), &partition));
  ASSERT_EQ(0, ndmSavePartitionTable(ndm_driver_.ndm()));

  auto header = reinterpret_cast<const HeaderV2*>(ndm_driver_.data(kControlPage0 + 2));
  EXPECT_EQ(0xffff, header->major_version);

  header = reinterpret_cast<const HeaderV2*>(ndm_driver_.data(kControlPage1));
  EXPECT_EQ(0xffff, header->major_version);
}

TEST_F(NdmTest, SavesUpdatedPartitionData) {
  NDMPartitionInfo partition = {};
  partition.basic_data.num_blocks = ndmGetNumVBlocks(ndm_driver_.ndm());
  ASSERT_EQ(0, ndmWritePartitionInfo(ndm_driver_.ndm(), &partition));

  // Write three new control blocks.
  ASSERT_EQ(0, ndmSavePartitionTable(ndm_driver_.ndm()));
  ASSERT_EQ(0, ndmSavePartitionTable(ndm_driver_.ndm()));
  ASSERT_EQ(0, ndmSavePartitionTable(ndm_driver_.ndm()));

  auto header = reinterpret_cast<const HeaderV2*>(ndm_driver_.data(kControlPage0 + 1));
  EXPECT_EQ(2, header->major_version);
  EXPECT_EQ(1, header->v1.sequence_num);

  header = reinterpret_cast<const HeaderV2*>(ndm_driver_.data(kControlPage0 + 2));
  EXPECT_EQ(2, header->major_version);
  EXPECT_EQ(2, header->v1.sequence_num);

  header = reinterpret_cast<const HeaderV2*>(ndm_driver_.data(kControlPage0 + 3));
  EXPECT_EQ(2, header->major_version);
  EXPECT_EQ(3, header->v1.sequence_num);

  header = reinterpret_cast<const HeaderV2*>(ndm_driver_.data(kControlPage0 + 4));
  EXPECT_EQ(0xffff, header->major_version);

  header = reinterpret_cast<const HeaderV2*>(ndm_driver_.data(kControlPage1));
  EXPECT_EQ(0xffff, header->major_version);
}

union PartitionInfo {
  NDMPartitionInfo ndm;
  struct {
    NDMPartition basic_data;
    uint32_t data_size;
    uint32_t data;
  } exploded;
};
static_assert(sizeof(NDMPartition) + sizeof(uint32_t) == sizeof(NDMPartitionInfo));
static_assert(sizeof(NDMPartitionInfo) + sizeof(uint32_t) == sizeof(PartitionInfo));

// Tests that the user portion of the partition info can grow.
TEST_F(NdmTest, UpdatesUserData) {
  NDMPartitionInfo partition = {};
  partition.basic_data.num_blocks = ndmGetNumVBlocks(ndm_driver_.ndm());
  ASSERT_EQ(0, ndmWritePartitionInfo(ndm_driver_.ndm(), &partition));
  ASSERT_EQ(0, ndmSavePartitionTable(ndm_driver_.ndm()));

  // Reinitialize NDM.
  EXPECT_TRUE(ndm_driver_.Detach());
  ASSERT_EQ(nullptr, ndm_driver_.Attach(nullptr));

  // Redefine the partition.
  PartitionInfo new_info = {};
  new_info.exploded.basic_data = partition.basic_data;
  new_info.exploded.data_size = sizeof(new_info.exploded.data);
  new_info.exploded.data = 42;
  ASSERT_EQ(0, ndmWritePartitionInfo(ndm_driver_.ndm(), &new_info.ndm));
  ASSERT_EQ(0, ndmSavePartitionTable(ndm_driver_.ndm()));

  // Read the latest version from disk.
  EXPECT_TRUE(ndm_driver_.Detach());
  ASSERT_EQ(nullptr, ndm_driver_.Attach(nullptr));

  const NDMPartitionInfo* info = ndmGetPartitionInfo(ndm_driver_.ndm());
  ASSERT_NE(nullptr, info);
  ASSERT_EQ(sizeof(new_info.exploded.data), info->user_data.data_size);

  auto actual_info = reinterpret_cast<const PartitionInfo*>(info);
  EXPECT_EQ(42u, actual_info->exploded.data);

  // Verify the expected disk layout.
  auto header = reinterpret_cast<const HeaderV2*>(ndm_driver_.data(kControlPage0 + 1));
  EXPECT_EQ(2, header->major_version);
  EXPECT_EQ(1, header->v1.sequence_num);

  header = reinterpret_cast<const HeaderV2*>(ndm_driver_.data(kControlPage1));
  EXPECT_EQ(2, header->major_version);
  EXPECT_EQ(2, header->v1.sequence_num);

  header = reinterpret_cast<const HeaderV2*>(ndm_driver_.data(kControlPage0 + 2));
  EXPECT_EQ(0xffff, header->major_version);

  header = reinterpret_cast<const HeaderV2*>(ndm_driver_.data(kControlPage1 + 1));
  EXPECT_EQ(0xffff, header->major_version);
}

TEST_F(NdmTest, BaseDriverSavesConfig) {
  ASSERT_EQ(nullptr, ndm_driver_.CreateVolume());

  const NDMPartitionInfo* info = ndmGetPartitionInfo(ndm_driver_.ndm());
  ASSERT_NE(nullptr, info);
  ASSERT_GE(info->user_data.data_size, 96u);  // Size of the first version of the data.

  const ftl::VolumeOptions* options = ndm_driver_.GetSavedOptions();
  ASSERT_NE(nullptr, options);
  ASSERT_EQ(memcmp(&kDefaultOptions, options, sizeof(*options)), 0);
}

class NdmReadOnlyTest : public ::testing::Test {
 public:
  void SetUp() override {
    ASSERT_TRUE(ftl::InitModules());
    ftl::VolumeOptions options = kDefaultOptions;
    options.flags |= ftl::kReadOnlyInit;
    ndm_driver_.reset(new NdmRamDriver(options));
    ASSERT_EQ(nullptr, ndm_driver_->Init());
    buffer_ = std::vector<uint8_t>(kPageSize, 0xff);
  }

 protected:
  std::unique_ptr<NdmRamDriver> ndm_driver_;
  std::vector<uint8_t> buffer_;
};

// An NDM control block version 1, stored on page 29.
constexpr uint32_t kControl29V1[] = {
    0x00010001, 0x00000000, 0x4efa26dd, 0x0000001e, 0x00010000, 0x0000001d, 0x0000001c, 0x0000001a,
    0x0000001b, 0xffffffff, 0x00000000, 0x0000001e, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff};

constexpr uint32_t kControlOob[] = {0x4d444eff, 0x31304154, 0xffffffff, 0x00ffffff};

TEST_F(NdmReadOnlyTest, Version1Only) {
  memcpy(buffer_.data(), kControl29V1, sizeof(kControl29V1));
  ASSERT_EQ(ftl::kNdmOk, ndm_driver_->NandWrite(kControlPage0, 1, buffer_.data(), kControlOob));

  ASSERT_EQ(nullptr, ndm_driver_->CreateVolume());
}

// An NDM control block version 2.0, stored on page 29.
constexpr uint32_t kControl29V2[] = {
    0x00000002, 0x00010001, 0x00000000, 0x061cc64a, 0x0000001e, 0x00010000, 0x0000001d, 0x0000001c,
    0x0000001a, 0x0000001b, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x0000001e, 0xffffffff};

TEST_F(NdmReadOnlyTest, Version2Only) {
  memcpy(buffer_.data(), kControl29V2, sizeof(kControl29V2));
  ASSERT_EQ(ftl::kNdmOk, ndm_driver_->NandWrite(kControlPage0, 1, buffer_.data(), kControlOob));

  ASSERT_EQ(nullptr, ndm_driver_->CreateVolume());
}

// An NDM control block version 2.0, stored on page 28, with partition data.
constexpr uint32_t kControl28V2[] = {
    0x00000002, 0x00010001, 0x00000001, 0x41220f07, 0x0000001e, 0x00010000, 0x0000001d, 0x0000001c,
    0x0000001a, 0x0000001b, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000001, 0x0000001e, 0xffffffff,
    0xffffffff, 0x00000000, 0x0000001a, 0x006c7466, 0x00000000, 0x00000000, 0x00000000, 0x00000060,
    0x00000001, 0x00000004, 0x00000006, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    0x0000001e, 0x00000002, 0x00010000, 0x00001000, 0x00000010, 0x00000000, 0x00000000, 0x00000000,
    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000};

TEST_F(NdmReadOnlyTest, UpgradedVersion2) {
  memcpy(buffer_.data(), kControl29V1, sizeof(kControl29V1));
  ASSERT_EQ(ftl::kNdmOk, ndm_driver_->NandWrite(kControlPage0, 1, buffer_.data(), kControlOob));

  memcpy(buffer_.data(), kControl28V2, sizeof(kControl28V2));
  ASSERT_EQ(ftl::kNdmOk, ndm_driver_->NandWrite(kControlPage1, 1, buffer_.data(), kControlOob));
  ASSERT_EQ(nullptr, ndm_driver_->CreateVolume());
}

// An NDM control block version 1, stored on page 29, with one factory bad block and
// a second bad block in the process of being relocated.
constexpr uint32_t kControlBlockTransferV1[] = {
    0x00010001, 0x00000001, 0xcd0deda6, 0x0000001e, 0x00010000, 0x0000001d, 0x0000001c, 0xffffffff,
    0xffffffff, 0x0000001b, 0x00000003, 0x0000000d, 0x00000102, 0x00000000, 0x00001e00, 0x00000300,
    0x00001b00, 0xffffff00, 0xffffffff, 0x000000ff, 0x00001a00, 0x6c746600, 0x00000000, 0x00000000,
    0x00000000, 0xffffff00, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff};

TEST_F(NdmReadOnlyTest, InTransferV1) {
  memcpy(buffer_.data(), kControlBlockTransferV1, sizeof(kControlBlockTransferV1));
  ASSERT_EQ(ftl::kNdmOk, ndm_driver_->NandWrite(kControlPage0, 1, buffer_.data(), kControlOob));

  ASSERT_NE(nullptr, ndm_driver_->CreateVolume());
  ASSERT_EQ(NDM_BAD_BLK_RECOV, GetFsErrCode());
}

// An NDM control block version 1, stored on page 29, with one factory bad block and
// one translated bad block.
constexpr uint32_t kControlBlockBadBlocksV1[] = {
    0x00010001, 0x00000002, 0x64342dc5, 0x0000001e, 0x00010000, 0x0000001d, 0x0000001c, 0xffffffff,
    0xffffffff, 0xffffffff, 0x00000001, 0x00000000, 0x0000001e, 0x00000003, 0x0000001b, 0xffffffff,
    0xffffffff, 0x00000000, 0x0000001a, 0x006c7466, 0x00000000, 0x00000000, 0x00000000, 0xffffffff};

TEST_F(NdmReadOnlyTest, BadBlocksV1) {
  memcpy(buffer_.data(), kControlBlockBadBlocksV1, sizeof(kControlBlockBadBlocksV1));
  ASSERT_EQ(ftl::kNdmOk, ndm_driver_->NandWrite(kControlPage0, 1, buffer_.data(), kControlOob));

  ASSERT_EQ(nullptr, ndm_driver_->CreateVolume());
  EXPECT_EQ(2u, ndm_driver_->ndm()->num_bad_blks);
}

// An NDM control block version 2.0, stored on page 29, with one factory bad block and
// a second bad block in the process of being relocated.
constexpr uint32_t kControlBlockTransferV2[] = {
    0x00000002, 0x00010001, 0x00000001, 0xdc1fd63c, 0x0000001e, 0x00010000, 0x0000001d, 0x0000001c,
    0xffffffff, 0xffffffff, 0x0000001b, 0x00000003, 0x0000000d, 0x00000001, 0x00000000, 0x0000001e,
    0x00000003, 0x0000001b, 0xffffffff, 0xffffffff, 0x00000000, 0x0000001a, 0x006c7466, 0x00000000,
    0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff};

TEST_F(NdmReadOnlyTest, InTransferV2) {
  memcpy(buffer_.data(), kControlBlockTransferV2, sizeof(kControlBlockTransferV2));
  ASSERT_EQ(ftl::kNdmOk, ndm_driver_->NandWrite(kControlPage0, 1, buffer_.data(), kControlOob));

  ASSERT_NE(nullptr, ndm_driver_->CreateVolume());
  ASSERT_EQ(NDM_BAD_BLK_RECOV, GetFsErrCode());
}

// An NDM control block version 2.0, stored on page 29, with one factory bad block and
// one translated bad block.
constexpr uint32_t kControlBlockBadBlocksV2[] = {
    0x00000002, 0x00010001, 0x00000002, 0x01148752, 0x0000001e, 0x00010000, 0x0000001d, 0x0000001c,
    0xffffffff, 0xffffffff, 0xffffffff, 0x00000003, 0x0000000d, 0x00000001, 0x00000000, 0x0000001e,
    0x00000003, 0x0000001b, 0xffffffff, 0xffffffff, 0x00000000, 0x0000001a, 0x006c7466, 0x00000000,
    0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff};

TEST(NdmReadOnlyTestWithLogger, BadBlocksV2) {
  static bool logger_called = false;
  logger_called = false;

  class LoggerHelper {
   public:
    static void Log(const char*, int, const char* _, ...) __PRINTFLIKE(3, 4) {
      logger_called = true;
    }
  };

  FtlLogger logger;
  logger.trace = &LoggerHelper::Log;
  logger.debug = &LoggerHelper::Log;
  logger.info = &LoggerHelper::Log;
  logger.warn = &LoggerHelper::Log;
  logger.error = &LoggerHelper::Log;

  ASSERT_TRUE(ftl::InitModules());
  ftl::VolumeOptions options = kDefaultOptions;
  options.flags |= ftl::kReadOnlyInit;
  auto ndm_driver = std::make_unique<NdmRamDriver>(options, logger);
  ASSERT_EQ(nullptr, ndm_driver->Init());
  std::vector<uint8_t> buffer(kPageSize, 0xff);

  memcpy(buffer.data(), kControlBlockBadBlocksV2, sizeof(kControlBlockBadBlocksV2));
  ASSERT_EQ(ftl::kNdmOk, ndm_driver->NandWrite(kControlPage0, 1, buffer.data(), kControlOob));

  ASSERT_EQ(nullptr, ndm_driver->CreateVolume());
  EXPECT_EQ(2u, ndm_driver->ndm()->num_bad_blks);
  EXPECT_TRUE(logger_called);
}

}  // namespace
