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

#ifndef SRC_STORAGE_MINFS_BUFFER_VIEW_H_
#define SRC_STORAGE_MINFS_BUFFER_VIEW_H_

#include <lib/fit/function.h>
#include <zircon/assert.h>
#include <zircon/types.h>

#include <variant>

#include <storage/buffer/block_buffer.h>

#include "src/storage/minfs/block_utils.h"

namespace minfs {

// Wraps either a regular pointer or a BlockBuffer. This exists because the mapped address for a
// storage::BlockBuffer isn't stable. In particular, a BlockBuffer that happens to be a resizeable
// VMO, can have its mapping change when it grows. When that happens, we don't want a BufferView to
// be invalidated, so we wrap a BlockBuffer and always call through to get the current mapped
// address.
class BufferPtr {
 public:
  BufferPtr() : ptr_(std::in_place_index<0>, nullptr) {}

  BufferPtr(const BufferPtr&) = default;
  BufferPtr& operator=(const BufferPtr&) = default;

  static BufferPtr FromMemory(void* buffer) {
    return BufferPtr(Ptr(std::in_place_index<0>, buffer));
  }

  static BufferPtr FromBlockBuffer(storage::BlockBuffer* buffer) {
    return BufferPtr(Ptr(std::in_place_index<1>, buffer));
  }

  void* get() const {
    if (std::holds_alternative<void*>(ptr_)) {
      return std::get<void*>(ptr_);
    } else {
      return std::get<storage::BlockBuffer*>(ptr_)->Data(0);
    }
  }

 private:
  using Ptr = std::variant<void*, storage::BlockBuffer*>;

  explicit BufferPtr(Ptr ptr) : ptr_(ptr) {}

  std::variant<void*, storage::BlockBuffer*> ptr_;
};

// BaseBufferView and BufferView are views of a buffer, a contiguous range in memory. It can be
// mutable or immutable. It keeps track of the use of mutable methods to record whether or not it is
// dirty. A flusher object is provided for flushing the buffer and is called via the Flush method if
// the buffer is deemed dirty. If no flusher is provided, the view is considered immutable. The
// underlying buffer can be memory, or it can be a BlockBuffer which we specialise for, in case
// BlockBuffer is resized, in which case its mapped address can change.
class BaseBufferView {
 public:
  using Flusher = fit::function<zx::result<>(BaseBufferView* view)>;

  BaseBufferView() = default;

  explicit BaseBufferView(BufferPtr buffer, size_t offset, size_t length)
      : buffer_(buffer), offset_(offset), length_(length) {}
  explicit BaseBufferView(BufferPtr buffer, size_t offset, size_t length, Flusher flusher)
      : buffer_(buffer), offset_(offset), length_(length), flusher_(std::move(flusher)) {}

  // Movable, but not copyable.
  BaseBufferView(BaseBufferView&& other) noexcept { *this = std::move(other); }
  BaseBufferView& operator=(BaseBufferView&& other) noexcept;

  ~BaseBufferView();

  bool IsValid() const { return data() != nullptr; }
  size_t length() const { return length_; }
  size_t offset() const { return offset_; }
  ByteRange GetByteRange() const { return ByteRange(offset_, offset_ + length_); }
  bool dirty() const { return dirty_; }
  void set_dirty(bool v) {
    ZX_ASSERT(data() != nullptr);
    ZX_ASSERT(flusher_);
    dirty_ = v;
  }

  // Does nothing if the buffer is not dirty. The buffer is always marked clean after calling flush;
  // it is up to the caller to handle errors appropriately.
  [[nodiscard]] zx::result<> Flush();

 protected:
  // N.B. Take care with the 'as' methods and alignment. On some architectures, unaligned access is
  // a problem, so if you're trying to access, say, a uint32_t at offset 5, you'll have an issue.

  // Returns const T&.
  template <typename T>
  const T& as() const {
    ZX_ASSERT(data() != nullptr);
    ZX_ASSERT(sizeof(T) <= length_);
    return *reinterpret_cast<T*>(data());
  }

  // Returns T&.
  template <typename T>
  T& as_mut() {
    ZX_ASSERT(data() != nullptr);
    ZX_ASSERT(sizeof(T) <= length_);
    ZX_ASSERT(flusher_);
    dirty_ = true;
    return *reinterpret_cast<T*>(data());
  }

 private:
  void* data() const { return static_cast<uint8_t*>(buffer_.get()) + offset_; }

  BufferPtr buffer_;
  size_t offset_ = 0;
  size_t length_ = 0;
  bool dirty_ = false;
  Flusher flusher_;
};

// BufferView is a typed version of BaseBufferView which will make it appear to be an array of
// objects of type T.
template <typename T>
class BufferView : public BaseBufferView {
 public:
  BufferView() = default;

  // |buffer| needs to be aligned sufficiently for T.
  BufferView(BufferPtr buffer, size_t index, size_t count)
      : BaseBufferView(buffer, sizeof(T) * index, sizeof(T) * count) {}
  BufferView(BufferPtr buffer, size_t index, size_t count, Flusher flusher)
      : BaseBufferView(buffer, sizeof(T) * index, sizeof(T) * count, std::move(flusher)) {}

  // Movable, but not copyable.
  BufferView(BufferView&& other) = default;
  BufferView& operator=(BufferView&& other) = default;

  const T* data() const { return &as<T>(); }
  size_t count() const { return length() / sizeof(T); }

  // Non mutating accessors.
  const T& operator*() const { return as<T>(); }
  const T& operator[](size_t index) const {
    ZX_ASSERT(index < count());
    return (&as<T>())[index];
  }

  // Mutating accessors.
  T& mut_ref() { return as_mut<T>(); }
  T& mut_ref(size_t index) {
    ZX_ASSERT(index < count());
    return (&as_mut<T>())[index];
  }
};

}  // namespace minfs

#endif  // SRC_STORAGE_MINFS_BUFFER_VIEW_H_
