// 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_FD_H_
#define SRC_LIB_ELFLDLTL_INCLUDE_LIB_ELFLDLTL_FD_H_

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

#include <cerrno>

#include <fbl/unique_fd.h>

#include "file.h"
#include "posix.h"

namespace elfldltl {

// elfldltl::UniqueFdFile is constructible from fbl::unique_fd and meets the
// File API (see <lib/elfldltl/memory.h>) by calling pread.  The same thing
// for unowned plain `int` file descriptors is provided by elfldltl::FdFile.

namespace internal {

inline fit::result<PosixError> ReadFd(int fd, off_t offset, cpp20::span<std::byte> buffer) {
  do {
    ssize_t n = pread(fd, buffer.data(), buffer.size(), offset);
    if (n < 0) {
      return fit::error{PosixError{errno}};
    }
    if (n == 0) {
      return fit::error{PosixError{}};  // This signifies EOF.
    }
    buffer = buffer.subspan(static_cast<size_t>(n));
    offset += n;
  } while (!buffer.empty());
  return fit::ok();
}

inline int MakeInvalidFd() { return -1; }

inline fit::result<PosixError> ReadUniqueFd(const fbl::unique_fd& fd, off_t offset,
                                            cpp20::span<std::byte> buffer) {
  return ReadFd(fd.get(), offset, buffer);
}

}  // namespace internal

template <class Diagnostics>
using FdFileBase = File<Diagnostics, int, off_t, internal::ReadFd, internal::MakeInvalidFd>;

template <class Diagnostics>
using UniqueFdFileBase = File<Diagnostics, fbl::unique_fd, off_t, internal::ReadUniqueFd>;

template <class Diagnostics>
class FdFile : public FdFileBase<Diagnostics> {
 public:
  using FdFileBase<Diagnostics>::FdFileBase;

  FdFile(const FdFile&) noexcept = default;

  FdFile(FdFile&&) noexcept = default;

  FdFile& operator=(const FdFile&) noexcept = default;

  FdFile& operator=(FdFile&&) noexcept = default;

  int borrow() const { return this->get(); }
};

// Deduction guide.
template <class Diagnostics>
FdFile(int fd, Diagnostics& diagnostics) -> FdFile<Diagnostics>;

template <class Diagnostics>
FdFile(Diagnostics& diagnostics) -> FdFile<Diagnostics>;

template <class Diagnostics>
class UniqueFdFile : public UniqueFdFileBase<Diagnostics> {
 public:
  using Base = UniqueFdFileBase<Diagnostics>;

  using Base::Base;

  UniqueFdFile(UniqueFdFile&&) noexcept = default;

  UniqueFdFile& operator=(UniqueFdFile&&) noexcept = default;

  int get() const { return Base::get().get(); }

  int borrow() const { return get(); }
};

// Deduction guide.
template <class Diagnostics>
UniqueFdFile(fbl::unique_fd fd, Diagnostics& diagnostics) -> UniqueFdFile<Diagnostics>;

template <class Diagnostics>
UniqueFdFile(Diagnostics& diagnostics) -> UniqueFdFile<Diagnostics>;

}  // namespace elfldltl

#endif  // SRC_LIB_ELFLDLTL_INCLUDE_LIB_ELFLDLTL_FD_H_
