// Copyright 2020 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 "flash_stress.h"

#include <fuchsia/hardware/block/cpp/fidl.h>
#include <fuchsia/hardware/block/cpp/fidl_test_base.h>
#include <lib/zx/fifo.h>
#include <lib/zx/status.h>
#include <lib/zx/time.h>
#include <lib/zx/vmo.h>

#include <random>
#include <thread>

#include <fbl/unique_fd.h>
#include <fs-management/fvm.h>
#include <gtest/gtest.h>

#include "src/lib/testing/predicates/status.h"
#include "src/storage/testing/fvm.h"
#include "src/storage/testing/ram_disk.h"
#include "status.h"
#include "testing_util.h"

namespace hwstress {
namespace {

constexpr size_t kBlockSize = 512;
constexpr size_t kDefaultRamDiskSize = 64 * 1024 * 1024;
constexpr size_t kDefaultFvmSliceSize = 1024 * 1024;
constexpr size_t kTestSize = 4 * 1024 * 1024;
// We deliberately select something that is not a multiple of kTransferSize.
constexpr size_t kTransferSize = 768 * 1024;
constexpr size_t kVmoSize = kTransferSize * /*kMaxInFlightRequests*/ 8;

class FakeBlock : public fuchsia::hardware::block::testing::Block_TestBase {
 public:
  FakeBlock(bool introduce_incorrect_reads, uint64_t device_size)
      : introduce_incorrect_reads_(introduce_incorrect_reads), device_size_(device_size) {}

  void GetFifo(GetFifoCallback callback) override {
    zx::fifo fifo;
    zx_status_t status =
        zx::fifo::create(/*elem_count=*/BLOCK_FIFO_MAX_DEPTH, /*elem_size=*/BLOCK_FIFO_ESIZE,
                         /*options=*/0, &fifo_, &fifo);
    callback(status, std::move(fifo));
  }

  void AttachVmo(::zx::vmo vmo, AttachVmoCallback callback) override {
    ZX_ASSERT(!vmo_.is_valid());
    vmo_ = std::move(vmo);
    uint64_t vmo_size;
    ZX_ASSERT(vmo_.get_size(&vmo_size) == ZX_OK);
    // Map the VMO into memory.
    zx_status_t status = zx::vmar::root_self()->map(
        /*options=*/(ZX_VM_PERM_READ | ZX_VM_PERM_WRITE | ZX_VM_MAP_RANGE),
        /*vmar_offset=*/0, vmo_, /*vmo_offset=*/0, vmo_size, &vmo_addr_);
    ZX_ASSERT(status == ZX_OK);
    callback(ZX_OK, std::make_unique<fuchsia::hardware::block::VmoId>(kVmoId));
  }

  void StartServer() {
    thread_ = std::make_unique<std::thread>([this]() { this->ServerLoop(); });
  }

  void CloseServer() {
    fifo_.signal(0, ZX_USER_SIGNAL_0);
    thread_->join();
  }

  // Callback when a unimplemented FIDL method is called.
  void NotImplemented_(const std::string& name) override {
    ZX_PANIC("Unimplemented: %s", name.c_str());
  }

 private:
  static constexpr fuchsia::hardware::block::VmoId kVmoId{.id = 42};
  bool introduce_incorrect_reads_;
  uint64_t device_size_;
  zx::fifo fifo_;
  zx::vmo vmo_;
  zx_vaddr_t vmo_addr_;
  std::unique_ptr<std::thread> thread_;

  void ServerLoop() {
    std::vector<block_fifo_request_t> reqs;
    size_t expected_offset = 0;
    while (true) {
      zx_signals_t pending;
      // We want to test what happens if the block device sends requests back in a
      // different order than what they were sent to us in. Unfortunately, we have
      // no way of knowing when the client code is blocked waiting for a response
      // from us.
      //
      // Instead, we just keep waiting for more requests until the client code stops
      // sending new ones for 50 milliseconds. After such a pause, we shuffle all
      // in-flight requests and start sending them back in a different order.
      zx_status_t status = fifo_.wait_one(ZX_FIFO_READABLE | ZX_FIFO_PEER_CLOSED | ZX_USER_SIGNAL_0,
                                          zx::deadline_after(zx::msec(50)), &pending);

      if (status == ZX_OK && (pending & ZX_FIFO_READABLE) != 0) {
        block_fifo_request_t request;
        zx_status_t status = fifo_.read(sizeof(request), &request, 1, nullptr);
        ZX_ASSERT(status == ZX_OK);
        ZX_ASSERT(request.vmoid == kVmoId.id);
        // Check that the data is correct and that it is being written to the correct device
        // location.
        ZX_ASSERT(request.dev_offset == expected_offset);
        expected_offset = request.dev_offset + request.length;
        ZX_ASSERT(request.dev_offset < device_size_ * kBlockSize);
        if (request.opcode == BLOCKIO_WRITE) {
          uint64_t expected_value = request.dev_offset;
          uint64_t found_value =
              reinterpret_cast<uint64_t*>(vmo_addr_ + request.vmo_offset * kBlockSize)[0];
          ZX_ASSERT(found_value == expected_value);
        }
        reqs.push_back(request);
      }

      if (status == ZX_OK && (pending & ZX_FIFO_READABLE) == 0) {
        // Peer closed.
        return;
      }

      // There are no more requests waiting so send response.
      if (status == ZX_ERR_TIMED_OUT) {
        std::shuffle(std::begin(reqs), std::end(reqs), std::default_random_engine());
        for (block_fifo_request_t request : reqs) {
          if (request.opcode == BLOCKIO_READ) {
            for (size_t i = 0; i < request.length; i++) {
              uint64_t value = request.dev_offset + i;
              // If requested, simulate an incorrect read when we are half way through the test.
              if (introduce_incorrect_reads_ &&
                  (request.dev_offset + i) * kBlockSize == device_size_ / 2) {
                value++;
              }
              WriteSectorData(vmo_addr_ + (request.vmo_offset + i) * kBlockSize, value);
            }
          }
          block_fifo_response_t response = {
              .status = ZX_OK,
              .reqid = request.reqid,
          };
          status = fifo_.write(sizeof(response), &response, 1, nullptr);
          ZX_ASSERT(status == ZX_OK);
        }
        reqs.clear();
      }
    }
  }

  void WriteSectorData(zx_vaddr_t start, uint64_t value) {
    uint64_t num_words = kBlockSize / sizeof(value);
    uint64_t* data = reinterpret_cast<uint64_t*>(start);
    for (uint64_t i = 0; i < num_words; i++) {
      data[i] = value;
    }
  }
};

TEST(Flash, FlashStress) {
  // Create a RAM disk.
  zx::status<storage::RamDisk> ramdisk = storage::RamDisk::Create(
      /*block_size=*/kBlockSize, /*block_count=*/kDefaultRamDiskSize / kBlockSize);
  ASSERT_TRUE(ramdisk.is_ok());

  // Instantiate it as a FVM device.
  zx::status<std::string> fvm_path =
      storage::CreateFvmInstance(ramdisk->path(), kDefaultFvmSliceSize);
  ASSERT_TRUE(fvm_path.is_ok());

  CommandLineArgs args;
  args.fvm_path = fvm_path.value();
  args.mem_to_test_megabytes = 16;

  StatusLine status;
  ASSERT_TRUE(StressFlash(&status, args, zx::msec(1)));
}

TEST(Flash, WriteFlashIo) {
  testing::LoopbackConnectionFactory factory;

  // Create a fake block device and a connection to it.
  FakeBlock block(false, kTestSize);

  BlockDevice device = {
      .device = factory.CreateSyncPtrTo<fuchsia::hardware::block::Block>(&block),
  };

  device.vmo_size = kVmoSize;
  device.info.block_size = kBlockSize;

  ASSERT_EQ(SetupBlockFifo("/dev/fake", &device), ZX_OK);
  block.StartServer();
  ASSERT_EQ(FlashIo(device, kTestSize, kTransferSize, /*is_write_test=*/true), ZX_OK);

  block.CloseServer();
}

TEST(Flash, ReadFlashIo) {
  testing::LoopbackConnectionFactory factory;

  // Create a fake block device and a connection to it.
  FakeBlock block(false, kTestSize);

  BlockDevice device = {
      .device = factory.CreateSyncPtrTo<fuchsia::hardware::block::Block>(&block),
  };

  device.vmo_size = kVmoSize;
  device.info.block_size = kBlockSize;

  ASSERT_EQ(SetupBlockFifo("/dev/fake", &device), ZX_OK);
  block.StartServer();
  ASSERT_EQ(FlashIo(device, kTestSize, kTransferSize, /*is_write_test=*/false), ZX_OK);

  block.CloseServer();
}

TEST(Flash, ReadErrorFlashIo) {
  testing::LoopbackConnectionFactory factory;

  // Create a fake block device and a connection to it.
  FakeBlock block(true, kTestSize);

  BlockDevice device = {
      .device = factory.CreateSyncPtrTo<fuchsia::hardware::block::Block>(&block),
  };

  device.vmo_size = kVmoSize;
  device.info.block_size = kBlockSize;

  ASSERT_EQ(SetupBlockFifo("/dev/fake", &device), ZX_OK);
  block.StartServer();
  ASSERT_DEATH({ FlashIo(device, kTestSize, kTransferSize, /*is_write_test=*/false); }, "");

  block.CloseServer();
}

TEST(Flash, SingleBlock) {
  testing::LoopbackConnectionFactory factory;

  // Create a fake block device and a connection to it.
  FakeBlock block(false, kBlockSize);

  BlockDevice device = {
      .device = factory.CreateSyncPtrTo<fuchsia::hardware::block::Block>(&block),
  };

  device.vmo_size = kVmoSize;
  device.info.block_size = kBlockSize;

  ASSERT_EQ(SetupBlockFifo("/dev/fake", &device), ZX_OK);

  block.StartServer();
  ASSERT_EQ(FlashIo(device, kBlockSize, kBlockSize, /*is_write_test=*/true), ZX_OK);
  block.CloseServer();
}

TEST(Flash, DeletePartition) {
  // Create a RAM disk.
  zx::status<storage::RamDisk> ramdisk = storage::RamDisk::Create(
      /*block_size=*/kBlockSize, /*block_count=*/kDefaultRamDiskSize / kBlockSize);
  ASSERT_TRUE(ramdisk.is_ok());

  // Instantiate it as a FVM device.
  zx::status<std::string> fvm_path =
      storage::CreateFvmInstance(ramdisk->path(), kDefaultFvmSliceSize);
  ASSERT_TRUE(fvm_path.is_ok());

  // Access FVM.
  fbl::unique_fd fvm_fd(open(fvm_path.value().c_str(), O_RDWR));
  ASSERT_TRUE(fvm_fd);

  alloc_req_t request{.slice_count = 1, .name = "test-fs"};
  memcpy(request.guid, uuid::Uuid::Generate().bytes(), sizeof(request.guid));
  memcpy(request.type, kTestPartGUID.bytes(), sizeof(request.type));

  // Create a partition.
  fbl::unique_fd fd(fvm_allocate_partition(fvm_fd.get(), &request));
  ASSERT_TRUE(fd);

  StatusLine status;
  DestroyFlashTestPartitions(&status);
  ASSERT_TRUE(open_partition(nullptr, kTestPartGUID.bytes(), 0, nullptr) != ZX_OK);
}

}  // namespace
}  // namespace hwstress
