// Copyright 2017 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 "src/storage/fvm/sparse_reader.h"

#include <zircon/assert.h>

#include <algorithm>
#include <cinttypes>
#include <memory>
#include <utility>
#include <vector>

namespace fvm {

namespace {

class FileReader : public ReaderInterface {
 public:
  FileReader(fbl::unique_fd fd) : fd_(std::move(fd)) {}

  virtual ~FileReader() = default;

  virtual zx_status_t Read(void* buf, size_t buf_size, size_t* size_actual) final {
    auto n = read(fd_.get(), buf, buf_size);
    if (n < 0) {
      return ZX_ERR_IO;
    }
    *size_actual = static_cast<size_t>(n);
    return ZX_OK;
  }

 private:
  fbl::unique_fd fd_;
};

}  // namespace

using Buffer = internal::Buffer;

Buffer::Buffer() = default;
Buffer::Buffer(uint64_t offset, size_t size, uint64_t capacity) : capacity_(capacity) {
  info_.size = size;
  info_.offset = offset;
  data_.reset(new uint8_t[capacity]);
}
Buffer::Buffer(Buffer&&) = default;
Buffer& Buffer::operator=(Buffer&&) = default;
Buffer::~Buffer() = default;

bool Buffer::IsEmpty() const { return info_.offset == 0 && info_.size == 0; }

void Buffer::Write(uint8_t* data, size_t length) {
  ZX_ASSERT(length <= capacity_);
  // We should have read all previous data from buffer before writing more.
  ZX_ASSERT(IsEmpty());

  if (length > 0) {
    memcpy(data_.get(), data, length);
    info_.size = length;
  }
}

void Buffer::Read(uint8_t* target, size_t length, size_t* actual) {
  size_t cp_sz = std::min(length, info_.size);

  if (cp_sz > 0) {
    memcpy(target, data_.get() + info_.offset, cp_sz);
    info_.offset += cp_sz;
  }

  info_.size -= cp_sz;

  if (info_.size == 0) {
    info_.offset = 0;
  }

  *actual = cp_sz;
}

zx_status_t SparseReader::Create(fbl::unique_fd fd, std::unique_ptr<SparseReader>* out) {
  return SparseReader::CreateHelper(std::make_unique<FileReader>(std::move(fd)), true /* verbose */,
                                    out);
}
zx_status_t SparseReader::Create(std::unique_ptr<ReaderInterface> reader,
                                 std::unique_ptr<SparseReader>* out) {
  return SparseReader::CreateHelper(std::move(reader), true /* verbose */, out);
}
zx_status_t SparseReader::CreateSilent(fbl::unique_fd fd, std::unique_ptr<SparseReader>* out) {
  return SparseReader::CreateHelper(std::make_unique<FileReader>(std::move(fd)),
                                    false /* verbose */, out);
}

zx_status_t SparseReader::CreateHelper(std::unique_ptr<ReaderInterface> reader_intf, bool verbose,
                                       std::unique_ptr<SparseReader>* out) {
  std::unique_ptr<SparseReader> reader(new SparseReader(std::move(reader_intf), verbose));

  zx_status_t status;
  if ((status = reader->ReadMetadata()) != ZX_OK) {
    return status;
  }

  *out = std::move(reader);
  return ZX_OK;
}

SparseReader::SparseReader(std::unique_ptr<ReaderInterface> reader, bool verbose)
    : compressed_(false), verbose_(verbose), reader_(std::move(reader)) {}

zx_status_t SparseReader::ReadMetadata() {
  // Read sparse image header.
  fvm::SparseImage image;
  size_t actual;
  auto status = ReadRaw(reinterpret_cast<uint8_t*>(&image), sizeof(fvm::SparseImage), &actual);
  if (status != ZX_OK || actual != sizeof(fvm::SparseImage)) {
    fprintf(stderr, "failed to read the sparse header\n");
    return ZX_ERR_IO;
  }

  // Verify the header.
  if (image.magic != fvm::kSparseFormatMagic) {
    if (verbose_) {
      fprintf(stderr, "SparseReader: Bad magic (got %" PRIx64 ")\n", image.magic);
    }
    return ZX_ERR_BAD_STATE;
  } else if (image.version != fvm::kSparseFormatVersion) {
    fprintf(stderr, "SparseReader: Unexpected sparse file version\n");
    return ZX_ERR_BAD_STATE;
  }

  ZX_ASSERT(image.header_length > sizeof(image));
  metadata_.reset(new uint8_t[image.header_length]);
  memcpy(metadata_.get(), &image, sizeof(image));

  // Read remainder of metadata.
  size_t off = sizeof(image);
  while (off < image.header_length) {
    status = ReadRaw(&metadata_[off], image.header_length - off, &actual);
    if (status != ZX_OK) {
      fprintf(stderr, "SparseReader: Failed to read metadata\n");
      return status;
    }
    off += actual;
  }

  // If image is compressed, additional setup is required
  if (image.flags & fvm::kSparseFlagLz4) {
    if (verbose_) {
      printf("Found compressed file\n");
    }

    compressed_ = true;
    if (auto status = SetupLZ4(); status != ZX_OK) {
      return status;
    }
  }

  return ZX_OK;
}

zx_status_t SparseReader::SetupLZ4() {
  zx_status_t status;
  size_t actual;
  // Initialize decompression context
  LZ4F_errorCode_t errc = LZ4F_createDecompressionContext(&dctx_, LZ4F_VERSION);
  if (LZ4F_isError(errc)) {
    fprintf(stderr, "SparseReader: could not initialize decompression: %s\n",
            LZ4F_getErrorName(errc));
    return ZX_ERR_INTERNAL;
  }

  size_t src_sz = 4;
  size_t dst_sz = 0;
  std::unique_ptr<uint8_t[]> inbufptr(new uint8_t[src_sz]);

  uint8_t* inbuf = inbufptr.get();

  // Read first 4 bytes to let LZ4 tell us how much it expects in the first pass.
  status = ReadRaw(inbuf, src_sz, &actual);
  if (status != ZX_OK || actual < src_sz) {
    fprintf(stderr, "SparseReader: could not read from input\n");
    return ZX_ERR_IO;
  }

  // Run decompress once to find out how much data we should read for the next decompress run
  // Since we are not yet decompressing any actual data, the dst_buffer is null
  to_read_ = LZ4F_decompress(dctx_, nullptr, &dst_sz, inbuf, &src_sz, NULL);
  if (LZ4F_isError(to_read_)) {
    fprintf(stderr, "SparseReader: could not decompress header: %s\n", LZ4F_getErrorName(to_read_));
    return ZX_ERR_INTERNAL;
  }

  if (to_read_ > LZ4_MAX_BLOCK_SIZE) {
    to_read_ = LZ4_MAX_BLOCK_SIZE;
  }

  // Initialize data buffers
  if ((status = InitializeBuffer(LZ4_MAX_BLOCK_SIZE, &out_)) != ZX_OK) {
    return status;
  } else if ((status = InitializeBuffer(LZ4_MAX_BLOCK_SIZE, &in_)) != ZX_OK) {
    return status;
  }

  return ZX_OK;
}

zx_status_t SparseReader::InitializeBuffer(size_t size, Buffer* out_buffer) {
  if (size < LZ4_MAX_BLOCK_SIZE) {
    fprintf(stderr, "Buffer size must be >= %d\n", LZ4_MAX_BLOCK_SIZE);
    return ZX_ERR_INVALID_ARGS;
  }
  *out_buffer = Buffer(0, 0, size);
  return ZX_OK;
}

SparseReader::~SparseReader() {
  PrintStats();

  if (compressed_) {
    LZ4F_freeDecompressionContext(dctx_);
  }
}

fvm::SparseImage* SparseReader::Image() {
  return reinterpret_cast<fvm::SparseImage*>(metadata_.get());
}

fvm::PartitionDescriptor* SparseReader::Partitions() {
  return reinterpret_cast<fvm::PartitionDescriptor*>(reinterpret_cast<uintptr_t>(metadata_.get()) +
                                                     sizeof(fvm::SparseImage));
}

zx_status_t SparseReader::ReadData(uint8_t* data, size_t length, size_t* actual) {
#ifdef __Fuchsia__
  zx_ticks_t start = zx_ticks_get();
#endif
  size_t total_size = 0;
  if (compressed_) {
    if (out_.IsEmpty() && to_read_ == 0) {
      fprintf(stderr, "Attempting to read past end of the compressed extent. At offset: %lu\n",
              raw_bytes_read_);
      fprintf(stderr, "Last raw read of size %lu ended with:", in_.size());
      for (size_t i = in_.size() - std::min(16ul, in_.size()); i < in_.size(); ++i) {
        fprintf(stderr, " %#02x", in_.get()[i]);
      }
      fprintf(stderr, "\n");
      // There is no more to read
      return ZX_ERR_OUT_OF_RANGE;
    }

    // Read previously decompressed data from buffer if possible
    out_.Read(data, length, &total_size);

    // If we still have data to read, start decompression (reading more from fd as needed)
    while (total_size < length && to_read_ > 0) {
      // Make sure data to read does not exceed max, and both buffers are empty
      ZX_ASSERT(out_.IsEmpty());
      ZX_ASSERT(in_.IsEmpty());
      ZX_ASSERT(to_read_ <= in_.capacity());

      // Read specified amount from fd
      zx_status_t status;
      if ((status = ReadRaw(in_.get(), to_read_, &(in_.info()->size))) != ZX_OK) {
        return status;
      }

      size_t src_sz = in_.size();
      size_t next = 0;

      // Decompress all compressed data
      while (in_.offset() < to_read_) {
        size_t dst_sz = out_.capacity() - out_.size();
        next = LZ4F_decompress(dctx_, out_.get() + out_.size(), &dst_sz, in_.get() + in_.offset(),
                               &src_sz, NULL);
        if (LZ4F_isError(next)) {
          fprintf(stderr, "could not decompress input: %s\n", LZ4F_getErrorName(next));
          return -1;
        }

        out_.info()->size += dst_sz;
        in_.info()->offset += src_sz;
        in_.info()->size -= src_sz;
        src_sz = to_read_ - in_.offset();
      }

      // Make sure we have read all data from in_buf_
      if (in_.size() > 0) {
        return ZX_ERR_IO;
      }

      in_.info()->offset = 0;

      // Copy newly decompressed data from outbuf
      size_t cp = std::min(length - total_size, static_cast<size_t>(out_.size()));
      out_.Read(data + total_size, cp, &cp);
      total_size += cp;
      to_read_ = next;

      if (to_read_ > LZ4_MAX_BLOCK_SIZE) {
        to_read_ = LZ4_MAX_BLOCK_SIZE;
      }
    }
  } else {
    zx_status_t status = ReadRaw(data, length, &total_size);

    if (status != ZX_OK) {
      return status;
    }
  }

#ifdef __Fuchsia__
  total_time_ += zx_ticks_get() - start;
#endif
  *actual = total_size;
  return ZX_OK;
}

zx_status_t SparseReader::ReadRaw(uint8_t* data, size_t length, size_t* actual) {
#ifdef __Fuchsia__
  zx_ticks_t start = zx_ticks_get();
#endif
  zx_status_t status;
  size_t size_actual;
  size_t total_size = 0;
  size_t bytes_left = length;
  while ((status = reader_->Read(data + total_size, bytes_left, &size_actual)) == ZX_OK &&
         size_actual > 0) {
    total_size += size_actual;
    bytes_left -= size_actual;
    if (bytes_left == 0) {
      break;
    }
  }

#ifdef __Fuchsia__
  read_time_ += zx_ticks_get() - start;
#endif

  if (status != ZX_OK) {
    return status;
  }

  raw_bytes_read_ += total_size;
  *actual = total_size;
  return ZX_OK;
}

zx_status_t SparseReader::WriteDecompressed(fbl::unique_fd outfd) {
  if (!compressed_) {
    fprintf(stderr, "BlockReader: File is not compressed\n");
    return ZX_ERR_INVALID_ARGS;
  }

  // Update metadata and write to new file.
  fvm::SparseImage* image = Image();
  image->flags &= ~fvm::kSparseFlagLz4;

  if (write(outfd.get(), metadata_.get(), image->header_length) !=
      static_cast<ssize_t>(image->header_length)) {
    fprintf(stderr, "BlockReader: could not write header to out file\n");
    return -1;
  }

  // Read/write decompressed data in LZ4_MAX_BLOCK_SIZE chunks.
  while (true) {
    zx_status_t status;
    uint8_t data[LZ4_MAX_BLOCK_SIZE];
    size_t length;
    if ((status = ReadData(data, LZ4_MAX_BLOCK_SIZE, &length)) != ZX_OK) {
      if (status == ZX_ERR_OUT_OF_RANGE) {
        return ZX_OK;
      }

      return status;
    }

    if (write(outfd.get(), data, length) != static_cast<ssize_t>(length)) {
      fprintf(stderr, "BlockReader: failed to write to output\n");
      return ZX_ERR_IO;
    }
  }
}

void SparseReader::PrintStats() const {
  if (verbose_) {
    printf("Reading FVM from compressed file: %s\n", compressed_ ? "true" : "false");
    printf("Remaining bytes read into compression buffer:    \%" PRIuMAX "\n", in_.size());
    printf("Remaining bytes written to decompression buffer:\%" PRIuMAX "\n", out_.size());
#ifdef __Fuchsia__
    printf("Time reading bytes from sparse FVM file:   %lu (%lu s)\n", read_time_,
           read_time_ / zx_ticks_per_second());
    printf("Time reading bytes AND decompressing them: %lu (%lu s)\n", total_time_,
           total_time_ / zx_ticks_per_second());
#endif
  }
}

zx_status_t SparseReader::DecompressLZ4File(const char* in_file, const char* out_file) {
  fbl::unique_fd fd_in(open(in_file, O_RDONLY, 0644));
  if (!fd_in) {
    fprintf(stderr, "Unable to open input lz4 file %s\n", in_file);
    return ZX_ERR_IO;
  }

  fbl::unique_fd fd_out(open(out_file, O_RDWR | O_CREAT, 0644));
  if (!fd_out) {
    fprintf(stderr, "Unable to create output file %s\n", out_file);
    return ZX_ERR_IO;
  }

  std::unique_ptr<SparseReader> reader(
      new SparseReader(std::make_unique<FileReader>(std::move(fd_in)), false));
  reader->compressed_ = true;
  reader->SetupLZ4();
  // Read/write decompressed data in LZ4_MAX_BLOCK_SIZE chunks.
  std::vector<uint8_t> buffer(LZ4_MAX_BLOCK_SIZE);
  while (true) {
    zx_status_t status;
    size_t length;
    if ((status = reader->ReadData(buffer.data(), LZ4_MAX_BLOCK_SIZE, &length)) != ZX_OK) {
      if (status == ZX_ERR_OUT_OF_RANGE) {
        return ZX_OK;
      }
      return status;
    }

    if (write(fd_out.get(), buffer.data(), length) != static_cast<ssize_t>(length)) {
      fprintf(stderr, "BlockReader: failed to write to output\n");
      return ZX_ERR_IO;
    }
  }
  return ZX_OK;
}

}  // namespace fvm
