// 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 <block-client/cpp/block-device.h>
#include <zxtest/zxtest.h>

namespace fvm {
namespace {

using block_client::BlockDevice;

class MockDeviceBase : public BlockDevice {
 public:
  virtual ~MockDeviceBase() = default;
  zx_status_t ReadBlock(uint64_t block_num, uint64_t block_size, void* block) const final {
    return ZX_ERR_NOT_SUPPORTED;
  }
  zx_status_t FifoTransaction(block_fifo_request_t* requests, size_t count) final {
    return ZX_ERR_NOT_SUPPORTED;
  }
  zx_status_t GetDevicePath(size_t buffer_len, char* out_name, size_t* out_len) const final {
    return ZX_ERR_NOT_SUPPORTED;
  }
  zx_status_t BlockGetInfo(fuchsia_hardware_block_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 VolumeQuery(fuchsia_hardware_block_volume_VolumeInfo* out_info) const final {
    return ZX_ERR_NOT_SUPPORTED;
  }
  zx_status_t VolumeQuerySlices(const uint64_t* slices, size_t slices_count,
                                fuchsia_hardware_block_volume_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_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_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;
    } else {
      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_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
