// 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 "fvm/sparse-reader.h"

#include <cinttypes>
#include <utility>

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

zx_status_t SparseReader::CreateHelper(fbl::unique_ptr<ReaderInterface> reader_intf, bool verbose,
                                       fbl::unique_ptr<SparseReader>* out) {
    fbl::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(fbl::unique_ptr<ReaderInterface> reader, bool verbose)
    : compressed_(false), verbose_(verbose), reader_(std::move(reader)) {}

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

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

    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 = reader_->Read(&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;
        // 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;
        fbl::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 = reader_->Read(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
        zx_status_t status;
        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;
} // namespace fvm

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::sparse_image_t* SparseReader::Image() {
    return reinterpret_cast<fvm::sparse_image_t*>(metadata_.get());
}

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

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) {
            // 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 = fbl::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;
    }

    *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::sparse_image_t* 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
    }
}

} // namespace fvm
