// 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 "dump-file-stdio.h"

#include "buffer-impl.h"

namespace zxdump::internal {

DumpFile::Stdio::~Stdio() = default;

// Return the available subset of the requested data, a view valid for the
// life of the Stdio.
fit::result<Error, ByteView> DumpFile::Stdio::ReadPermanent(FileRange where) {
  auto result = Read(where);
  if (result.is_error()) {
    return result.take_error();
  }
  if (result->size() < where.size) {
    return TruncatedDump();
  }
  ByteView data{result->data(), result->size()};
  keepalive_.push_front(std::move(result).value());
  return fit::ok(data);
}

// Return the available subset of the requested data, a view valid only
// until the next call to this method.  The returned data might be less
// than what's requested if EOF is reached.
fit::result<Error, ByteView> DumpFile::Stdio::ReadProbe(FileRange where) {
  auto result = Read(where);
  if (result.is_error()) {
    return result.take_error();
  }
  ByteView data{result->data(), result->size()};
  ephemeral_buffer_ = std::move(result).value();
  ephemeral_buffer_range_ = where;
  return fit::ok(data);
}

// Return the available subset of the requested data, a view valid only
// until the next call to this method.  The data must be present.
fit::result<Error, ByteView> DumpFile::Stdio::ReadEphemeral(FileRange where) {
  auto result = ReadProbe(where);
  if (result.is_ok() && result->size() < where.size) {
    return TruncatedDump();
  }
  return result;
}

fit::result<Error, Buffer<>> DumpFile::Stdio::ReadMemory(FileRange where) {
  auto result = Read(where);
  if (result.is_error()) {
    return result.take_error();
  }
  Buffer<> buffer;
  auto copy = std::make_unique<BufferImplVector>(*std::move(result));
  buffer.data_ = std::span<std::byte>(*copy);
  buffer.impl_ = std::move(copy);
  return fit::ok(std::move(buffer));
}

fit::result<Error, DumpFile::ByteVector> DumpFile::Stdio::Read(FileRange where) {
  if (!stream_) {
    return fit::error(Error{"read_memory disabled", ZX_ERR_NOT_SUPPORTED});
  }

  // Seek if necessary and possible.
  if (where.offset != pos_ && !is_pipe_) {
    if (fseek(stream_.get(), static_cast<long int>(where.offset), SEEK_SET) == 0) {
      pos_ = where.offset;
    } else if (errno == ESPIPE) {
      is_pipe_ = true;
    } else {
      return fit::error(Error{"fseek", ZX_ERR_IO});
    }
  }

  // In general the reader can only ever need to look backward when attempting
  // random access for reading memory segments.  The one exception is after
  // reading the initial header probe with ReadEphemeral, when the next data
  // needed might overlap with the end of the probe that was more than it
  // turned out was actually needed for the header.  So in that case we can
  // steal the data from the ephemeral_buffer_ already on hand.
  ByteVector buffer(where.size);
  std::byte* data = buffer.data();
  while (where.offset < pos_) {
    ByteView old_data{ephemeral_buffer_.data(), ephemeral_buffer_range_.size};
    if (where.offset >= ephemeral_buffer_range_.offset) {
      size_t ofs = where.offset - ephemeral_buffer_range_.offset;
      if (ofs < old_data.size()) {
        size_t copied = std::min(old_data.size() - ofs, static_cast<size_t>(where.size));
        std::copy(old_data.begin() + ofs, old_data.begin() + ofs + copied, data);
        data += copied;
        where.offset += copied;
        where.size -= copied;
        continue;
      }
    }
    return fit::error(Error{"random access not available", ZX_ERR_IO_REFUSED});
  }

  // Not seekable, so just eat any data being skipped over.
  while (where.offset > pos_) {
    if (getc(stream_.get()) == EOF) {
      return fit::error(Error{"getc", ZX_ERR_IO});
    }
    ++pos_;
  }

  while (where.size > 0) {
    size_t n = fread(data, 1, where.size, stream_.get());
    if (n == 0) {
      if (feof(stream_.get())) {
        break;
      }
      return fit::error(Error{"fread", ZX_ERR_IO});
    }
    pos_ += n;
    data += n;
    where.size -= n;
  }
  buffer.resize(data - buffer.data());
  buffer.shrink_to_fit();
  return fit::ok(std::move(buffer));
}

}  // namespace zxdump::internal
