// 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 "src/storage/fvm/client.h"

#include <zxtest/zxtest.h>

#include "src/storage/lib/block_client/cpp/block_device.h"

namespace fvm {
namespace {

using block_client::BlockDevice;

class MockDeviceBase : public BlockDevice {
 public:
  ~MockDeviceBase() override = default;
  zx_status_t FifoTransaction(block_fifo_request_t* requests, size_t count) final {
    return ZX_ERR_NOT_SUPPORTED;
  }
  zx::result<std::string> GetTopologicalPath() const final {
    return zx::error(ZX_ERR_NOT_SUPPORTED);
  }
  zx::result<> Rebind(std::string_view url_suffix) const override {
    return zx::error(ZX_ERR_NOT_SUPPORTED);
  }
  zx_status_t BlockGetInfo(fuchsia_hardware_block::wire::BlockInfo* out_info) const final {
    return ZX_ERR_NOT_SUPPORTED;
  }
  zx_status_t BlockAttachVmo(const zx::vmo& vmo, storage::Vmoid* out_vmoid) final {
    return ZX_ERR_NOT_SUPPORTED;
  }
  zx_status_t VolumeGetInfo(
      fuchsia_hardware_block_volume::wire::VolumeManagerInfo* out_manager,
      fuchsia_hardware_block_volume::wire::VolumeInfo* out_volume) const final {
    return ZX_ERR_NOT_SUPPORTED;
  }
  zx_status_t VolumeQuerySlices(const uint64_t* slices, size_t slices_count,
                                fuchsia_hardware_block_volume::wire::VsliceRange* out_ranges,
                                size_t* out_ranges_count) const override {
    return ZX_ERR_NOT_SUPPORTED;
  }
  zx_status_t VolumeExtend(uint64_t offset, uint64_t length) final { return ZX_ERR_NOT_SUPPORTED; }
  zx_status_t VolumeShrink(uint64_t offset, uint64_t length) override {
    return ZX_ERR_NOT_SUPPORTED;
  }
};

TEST(FvmClientTest, ResetSlicesNotSupported) {
  MockDeviceBase device;
  ASSERT_EQ(ZX_ERR_NOT_SUPPORTED, ResetAllSlices(&device));
}

class MockBadDevice : public MockDeviceBase {
 public:
  zx_status_t VolumeQuerySlices(const uint64_t* slices, size_t slices_count,
                                fuchsia_hardware_block_volume::wire::VsliceRange* out_ranges,
                                size_t* out_ranges_count) const override {
    *out_ranges_count = 0;
    return ZX_OK;
  }
  zx_status_t VolumeShrink(uint64_t offset, uint64_t length) override { return ZX_OK; }
};

TEST(FvmClientTest, ResetSlicesBadDevice) {
  MockBadDevice device;
  ASSERT_EQ(ZX_ERR_IO, ResetAllSlices(&device));
}

//  [1, 10]: Allocated
class MockOneSliceRangeDevice : public MockDeviceBase {
 public:
  zx_status_t VolumeQuerySlices(const uint64_t* slices, size_t slices_count,
                                fuchsia_hardware_block_volume::wire::VsliceRange* out_ranges,
                                size_t* out_ranges_count) const override {
    EXPECT_EQ(1, slices_count);
    if (slices[0] == 1) {
      out_ranges[0].count = 10;
      out_ranges[0].allocated = true;
      *out_ranges_count = 1;
      return ZX_OK;
    }
    return ZX_ERR_OUT_OF_RANGE;
  }

  zx_status_t VolumeShrink(uint64_t offset, uint64_t length) override {
    EXPECT_EQ(1, offset);
    EXPECT_EQ(10, length);
    EXPECT_FALSE(shrink_called_);
    shrink_called_ = true;
    return ZX_OK;
  }

  bool shrink_called_ = false;
};

TEST(FvmClientTest, ResetSlicesOneSliceRange) {
  MockOneSliceRangeDevice device;
  EXPECT_OK(ResetAllSlices(&device));
  EXPECT_TRUE(device.shrink_called_);
}

//  [1, 10]: Allocated
// [11, 20]: Not Allocated
// [21, 30]: Allocated
class MockManySliceRangesDevice : public MockDeviceBase {
 public:
  zx_status_t VolumeQuerySlices(const uint64_t* slices, size_t slices_count,
                                fuchsia_hardware_block_volume::wire::VsliceRange* out_ranges,
                                size_t* out_ranges_count) const override {
    EXPECT_EQ(1, slices_count);
    switch (slices[0]) {
      case 1:
        out_ranges[0].count = 10;
        out_ranges[0].allocated = true;
        *out_ranges_count = 1;
        return ZX_OK;
      case 11:
        out_ranges[0].count = 10;
        out_ranges[0].allocated = false;
        *out_ranges_count = 1;
        return ZX_OK;
      case 21:
        out_ranges[0].count = 10;
        out_ranges[0].allocated = true;
        *out_ranges_count = 1;
        return ZX_OK;
      default:
        return ZX_ERR_OUT_OF_RANGE;
    }
  }

  zx_status_t VolumeShrink(uint64_t offset, uint64_t length) override {
    switch (offset) {
      case 1:
        EXPECT_EQ(10, length);
        EXPECT_FALSE(shrink_called_[0]);
        shrink_called_[0] = true;
        return ZX_OK;
      case 21:
        EXPECT_EQ(10, length);
        EXPECT_FALSE(shrink_called_[1]);
        shrink_called_[1] = true;
        return ZX_OK;
      default:
        return ZX_ERR_IO;
    }
  }

  bool shrink_called_[2] = {};
};

TEST(FvmClientTest, ResetSlicesManySliceRanges) {
  MockManySliceRangesDevice device;
  EXPECT_OK(ResetAllSlices(&device));
  EXPECT_TRUE(device.shrink_called_[0]);
  EXPECT_TRUE(device.shrink_called_[1]);
}

}  // namespace
}  // namespace fvm
