// Copyright 2022 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_LIB_ELFLDLTL_INCLUDE_LIB_ELFLDLTL_FILE_H_
#define SRC_LIB_ELFLDLTL_INCLUDE_LIB_ELFLDLTL_FILE_H_

#include <lib/fit/result.h>
#include <lib/stdcompat/span.h>

#include <optional>
#include <string_view>
#include <type_traits>
#include <utility>

#include "diagnostics.h"

namespace elfldltl {

template <typename Handle>
inline auto DefaultMakeInvalidHandle() {
  return Handle();
}

// elfldltl::File<Handle, Offset, Read, MakeInvalidHandle> implements the File
// API (see memory.h) by holding a Handle object and calling Read as a function
// fit::result<...>(Handle&, Offset, cpp20::span<byte>) that returns some error
// value that Diagnostics::SystemError can handle.  MakeInvalidHandle can be
// supplied if default-construction isn't the way.
template <class Diagnostics, typename Handle, typename Offset, auto Read,
          auto MakeInvalidHandle = &DefaultMakeInvalidHandle<Handle>>
class File {
 public:
  static_assert(std::is_invocable_v<decltype(Read), Handle&, Offset, cpp20::span<std::byte>>);
  static_assert(std::is_convertible_v<decltype(MakeInvalidHandle()), Handle>);

  using offset_type = Offset;

  File(const File&) noexcept(std::is_nothrow_copy_constructible_v<Handle>) = default;

  File(File&&) noexcept(std::is_nothrow_move_constructible_v<Handle>) = default;
  explicit File(Diagnostics& diag) : diag_(diag) {}

  File(Handle handle, Diagnostics& diag) noexcept(std::is_nothrow_move_constructible_v<Handle>)
      : handle_(std::move(handle)), diag_(diag) {}

  File& operator=(const File&) noexcept(std::is_nothrow_copy_assignable_v<Handle>) = default;

  File& operator=(File&&) noexcept(std::is_nothrow_move_assignable_v<Handle>) = default;

  const Handle& get() const { return handle_; }

  Handle release() { return std::exchange(handle_, MakeInvalidHandle()); }

  template <typename T>
  std::optional<T> ReadFromFile(Offset offset) {
    std::optional<T> result{std::in_place};
    cpp20::span<T> data{std::addressof(result.value()), 1};
    FinishReadFromFile(offset, data, result);
    return result;
  }

  template <typename T, typename Allocator>
  auto ReadArrayFromFile(off_t offset, Allocator&& allocator, size_t count) {
    auto result = allocator(count);
    if (result) {
      cpp20::span<T> data = *result;
      FinishReadFromFile(offset, data, result);
    }
    return result;
  }

 protected:
  Handle& handle() { return handle_; }
  const Handle& handle() const { return handle_; }

 private:
  template <typename T, typename Result>
  void FinishReadFromFile(Offset offset, cpp20::span<T> data, Result& result) {
    using namespace std::string_view_literals;
    auto read = Read(handle_, offset, cpp20::as_writable_bytes(data));
    if (read.is_error()) {
      // FileOffset takes an unsigned type, but off_t is signed.
      // No value passed to Read should be negative.
      auto diagnose = [offset = static_cast<std::make_unsigned_t<Offset>>(offset),
                       bytes = data.size_bytes(), this](auto&& error) {
        diag_.SystemError("cannot read "sv, bytes, " bytes"sv, FileOffset{offset}, ": "sv,
                          std::move(error));
      };
      auto error = std::move(read).error_value();
      if (error == decltype(error){}) {
        // The default-initialized error type is used to mean EOF.
        diagnose("reached end of file"sv);
      } else {
        diagnose(std::move(error));
      }
      result = Result();
    }
  }

  Handle handle_ = MakeInvalidHandle();
  Diagnostics& diag_;
};

}  // namespace elfldltl

#endif  // SRC_LIB_ELFLDLTL_INCLUDE_LIB_ELFLDLTL_FILE_H_
