// Copyright 2018 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 <stdio.h>
#include <unistd.h>

#include <blobfs/compression/compressor.h>
#include <blobfs/compression/lz4.h>
#include <fbl/algorithm.h>
#include <fbl/auto_call.h>
#include <fbl/macros.h>
#include <fbl/unique_ptr.h>
#include <lz4/lz4frame.h>
#include <fs/trace.h>
#include <zircon/types.h>

namespace blobfs {

constexpr size_t kLz4HeaderSize = 15;

LZ4Compressor::LZ4Compressor(LZ4F_compressionContext_t ctx, void* compression_buffer,
                             size_t compression_buffer_length)
    : ctx_(std::move(ctx)), buf_(compression_buffer), buf_max_(compression_buffer_length),
      buf_used_(0) {}

void* LZ4Compressor::Buffer() const {
    return reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(buf_) + buf_used_);
}

size_t LZ4Compressor::Remaining() const {
    return buf_max_ - buf_used_;
}

LZ4Compressor::~LZ4Compressor() {
    LZ4F_freeCompressionContext(ctx_);
}

zx_status_t LZ4Compressor::Create(size_t input_size, void* compression_buffer,
                                  size_t compression_buffer_length,
                                  fbl::unique_ptr<LZ4Compressor>* out) {
    if (BufferMax(input_size) > compression_buffer_length) {
        return ZX_ERR_BUFFER_TOO_SMALL;
    }

    LZ4F_compressionContext_t ctx;
    LZ4F_errorCode_t errc = LZ4F_createCompressionContext(&ctx, LZ4F_VERSION);
    if (LZ4F_isError(errc)) {
        return ZX_ERR_NO_MEMORY;
    }

    auto compressor = fbl::unique_ptr<LZ4Compressor>(new LZ4Compressor(std::move(ctx),
                                                                       compression_buffer,
                                                                       compression_buffer_length));
    size_t r = LZ4F_compressBegin(compressor->ctx_,
                                  compressor->Buffer(),
                                  compressor->Remaining(), nullptr);
    if (LZ4F_isError(r)) {
        return ZX_ERR_BUFFER_TOO_SMALL;
    }
    compressor->buf_used_ += r;

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

size_t LZ4Compressor::BufferMax(size_t blob_size) {
    return kLz4HeaderSize + LZ4F_compressBound(blob_size, nullptr);
}

zx_status_t LZ4Compressor::Update(const void* data, size_t length) {
    size_t r = LZ4F_compressUpdate(ctx_, Buffer(), Remaining(), data, length, nullptr);
    if (LZ4F_isError(r)) {
        return ZX_ERR_IO_DATA_INTEGRITY;
    }
    buf_used_ += r;
    return ZX_OK;
}

zx_status_t LZ4Compressor::End() {
    size_t r = LZ4F_compressEnd(ctx_, Buffer(), Remaining(), nullptr);
    if (LZ4F_isError(r)) {
        return ZX_ERR_IO_DATA_INTEGRITY;
    }
    buf_used_ += r;
    return ZX_OK;
}

size_t LZ4Compressor::Size() const {
    return buf_used_;
}

zx_status_t LZ4Decompress(void* target_buf_, size_t* target_size, const void* src_buf_,
                          size_t* src_size) {
    TRACE_DURATION("blobfs", "LZ4Decompress", "target_size", *target_size,
                   "src_size", *src_size);
    uint8_t* target_buf = reinterpret_cast<uint8_t*>(target_buf_);
    const uint8_t* src_buf = reinterpret_cast<const uint8_t*>(src_buf_);

    LZ4F_decompressionContext_t ctx;
    LZ4F_errorCode_t errc = LZ4F_createDecompressionContext(&ctx, LZ4F_VERSION);
    if (LZ4F_isError(errc)) {
        return ZX_ERR_NO_MEMORY;
    }

    auto cleanup = fbl::MakeAutoCall([&ctx]() {
        LZ4F_freeDecompressionContext(ctx);
    });
    size_t target_drained = 0;
    size_t src_drained = 0;

    // Decompress the first four bytes of the source without consuming the
    // destination buffer to determine the size of the frame header.
    size_t dst_sz_next = 0;
    size_t src_sz_next = 4;

    while (true) {
        uint8_t* target = target_buf + target_drained;
        const uint8_t* src = src_buf + src_drained;

        size_t r = LZ4F_decompress(ctx, target, &dst_sz_next, src, &src_sz_next, nullptr);
        if (LZ4F_isError(r)) {
            return ZX_ERR_IO_DATA_INTEGRITY;
        }

        // After the call to decompress, these are the sizes which were used.
        target_drained += dst_sz_next;
        src_drained += src_sz_next;

        if (r == 0) {
            break;
        }

        dst_sz_next = *target_size - target_drained;
        src_sz_next = r;

    }

    *target_size = target_drained;
    *src_size = src_drained;
    return ZX_OK;
}

} // namespace blobfs
