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

#include <lib/zxdump/fd-writer.h>
#include <sys/uio.h>
#include <unistd.h>
#include <zircon/assert.h>

#include <algorithm>
#include <cerrno>
#include <climits>
#include <utility>

namespace zxdump {

using namespace std::literals;

namespace {

auto ErrnoError(std::string_view op) { return fit::error{FdError{.op_ = op, .error_ = errno}}; }

}  // namespace

void FdWriter::Accumulate(size_t offset, ByteView data) {
  if (data.empty()) {
    return;
  }
  ZX_ASSERT_MSG(offset >= total_, "Accumulate %zu bytes at offset %zu vs total %zu", data.size(),
                offset, total_);
  ZX_ASSERT_MSG(offset - total_ == fragments_.size_bytes_,
                "Accumulate at %zu - %zu gap != %zu accumulation", offset, total_,
                fragments_.size_bytes_);
  fragments_.iov_.push_back({const_cast<std::byte*>(data.data()), data.size()});
  fragments_.size_bytes_ += data.size();
}

// Flush accumulated fragments.
fit::result<FdWriter::error_type, size_t> FdWriter::WriteFragments() {
  // Consume the old state.
  Fragments fragments = std::exchange(fragments_, {});

  // Drain the whole vector of fragments to write, making as few writev calls
  // as possible.
  size_t written = 0;
  for (size_t i = 0; i < fragments.iov_.size(); ++i) {
    ZX_DEBUG_ASSERT(written < fragments.size_bytes_);
    size_t count = std::min(size_t{IOV_MAX}, fragments.iov_.size() - i);
    ssize_t n = writev(fd_.get(), &fragments.iov_[i], static_cast<int>(count));
    if (n <= 0) {
      if (n == 0) {
        errno = EIO;
      }
      return ErrnoError("writev"sv);
    }
    size_t wrote = static_cast<size_t>(n);
    ZX_ASSERT(wrote <= fragments.size_bytes_ - written);
    written += wrote;

    // Trim off all the fragments that writev consumed.
    while (i < fragments.iov_.size() && fragments.iov_[i].iov_len <= wrote) {
      ZX_DEBUG_ASSERT(fragments.iov_[i].iov_len > 0);
      wrote -= fragments.iov_[i].iov_len;
      ++i;
    }

    // Adjust the next remaining fragment if writev wrote part of it.
    if (wrote > 0 && i < fragments.iov_.size()) {
      iovec& iov = fragments.iov_[i];
      ZX_DEBUG_ASSERT(iov.iov_len > wrote);
      iov.iov_len -= wrote;
      iov.iov_base = static_cast<std::byte*>(iov.iov_base) + wrote;
    }
  }

  total_ += written;
  ZX_ASSERT(written == fragments.size_bytes_);
  return fit::ok(written);
}

fit::result<FdWriter::error_type> FdWriter::Write(size_t offset, ByteView data) {
  ZX_ASSERT(offset >= total_);
  ZX_ASSERT(!data.empty());
  ZX_DEBUG_ASSERT(data.data());

  auto write_data = [this](ByteView data)  // Write the whole chunk.
      -> fit::result<FdWriter::error_type> {
    do {
      ssize_t n = write(fd_.get(), data.data(), data.size());
      if (n <= 0) {
        if (n == 0) {
          errno = EIO;
        }
        return ErrnoError("write");
      }
      const size_t wrote = static_cast<size_t>(n);
      ZX_ASSERT(wrote <= data.size());
      data = data.subspan(wrote);
      total_ += wrote;
    } while (!data.empty());
    return fit::ok();
  };

  // Seek or fill past any gap.
  const size_t gap = offset - total_;

  if (gap > 0) {
    // Pad ahead to the aligned offset.  Seek ahead to leave holes
    // in a sparse file if the filesystem supports that.
    if (!is_pipe_ && lseek(fd_.get(), static_cast<off_t>(gap), SEEK_CUR) < 0) {
      is_pipe_ = errno == ESPIPE;
      if (!is_pipe_) {
        return ErrnoError("lseek");
      }
    }
    if (is_pipe_) {
      // It's not seekable, so fill in with zero bytes.
      auto zero = std::make_unique<const std::byte[]>(gap);
      auto result = write_data({zero.get(), gap});
      if (result.is_error()) {
        return result;
      }
    } else {
      // When we write below, we will have "written" the gap bytes too.
      total_ = offset;
    }
  }

  // Now write the actual data and total_ will again reflect the end of file.
  return write_data(data);
}

}  // namespace zxdump
