// Copyright 2021 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <algorithm>
#include <vector>

#include "starboard/elf_loader/lz4_file_impl.h"

#include "starboard/common/log.h"
#include "starboard/common/time.h"
#include "starboard/extension/loader_app_metrics.h"
#include "starboard/memory.h"
#include "starboard/system.h"

namespace starboard {
namespace elf_loader {

LZ4FileImpl::LZ4FileImpl() {
  const LZ4F_errorCode_t lz4f_error_code =
      LZ4F_createDecompressionContext(&lz4f_context_, LZ4F_VERSION);

  if (lz4f_error_code != 0) {
    SB_LOG(ERROR) << LZ4F_getErrorName(lz4f_error_code);
    lz4f_context_ = nullptr;
  }
}

LZ4FileImpl::~LZ4FileImpl() {
  if (!lz4f_context_) {
    return;
  }

  const LZ4F_errorCode_t lz4f_error_code =
      LZ4F_freeDecompressionContext(lz4f_context_);

  if (lz4f_error_code != 0) {
    SB_LOG(ERROR) << LZ4F_getErrorName(lz4f_error_code);
  }
}

static size_t GetBlockSize(const LZ4F_frameInfo_t* frame_info) {
  switch (frame_info->blockSizeID) {
    case LZ4F_default:
    case LZ4F_max64KB:
      return 64 * (1 << 10);
    case LZ4F_max256KB:
      return 256 * (1 << 10);
    case LZ4F_max1MB:
      return 1 * (1 << 20);
    case LZ4F_max4MB:
      return 4 * (1 << 20);
    default:
      SB_LOG(INFO) << "Got an unknown block size; continuing with 256KB";
      return 256 * (1 << 10);
  }
}

bool LZ4FileImpl::Open(const char* name) {
  SB_DCHECK(name);

  if (!lz4f_context_) {
    return false;
  }

  SbFileInfo file_info;

  if (!FileImpl::Open(name) || !SbFileGetInfo(file_, &file_info)) {
    return false;
  }

  int64_t decompression_start_time_us = CurrentMonotonicTime();

  size_t header_size = PeekHeaderSize();
  if (LZ4F_isError(header_size)) {
    SB_LOG(ERROR) << LZ4F_getErrorName(header_size);
    return false;
  }

  LZ4F_frameInfo_t frame_info = LZ4F_INIT_FRAMEINFO;
  size_t source_bytes_hint = ConsumeHeader(&frame_info, header_size);
  if (LZ4F_isError(source_bytes_hint)) {
    SB_LOG(ERROR) << LZ4F_getErrorName(source_bytes_hint);
    LZ4F_resetDecompressionContext(lz4f_context_);
    return false;
  }

  // We require the uncompressed data size to be set in the LZ4 frame header so
  // that we can be aggressive with memory allocation during decompression.
  uint64_t content_size = frame_info.contentSize;
  if (content_size <= 0) {
    SB_LOG(ERROR) << "Content size must be present in the LZ4 frame header";
    return false;
  }
  decompressed_data_.resize(content_size);

  // LZ4F_decompress() expects (but does not require) to decode a specific
  // number of source bytes: the size of the current compressed block + the
  // header of the next block. We can meet this expectation often, without
  // allocating much extra space, by using a buffer of size equal to the
  // uncompressed block size.
  int max_compressed_buffer_size = GetBlockSize(&frame_info);

  bool result = Decompress(file_info.size, header_size,
                           max_compressed_buffer_size, source_bytes_hint);

  int64_t decompression_end_time_us = CurrentMonotonicTime();
  int64_t decompression_duration_us =
      decompression_end_time_us - decompression_start_time_us;
  SB_LOG(INFO) << "Decompression took: " << decompression_duration_us / 1000
               << " ms";
  auto metrics_extension =
      static_cast<const StarboardExtensionLoaderAppMetricsApi*>(
          SbSystemGetExtension(kStarboardExtensionLoaderAppMetricsName));
  if (metrics_extension &&
      strcmp(metrics_extension->name,
             kStarboardExtensionLoaderAppMetricsName) == 0 &&
      metrics_extension->version >= 2) {
    metrics_extension->SetElfDecompressionDurationMicroseconds(
        decompression_duration_us);
  }

  return result;
}

size_t LZ4FileImpl::PeekHeaderSize() {
  std::vector<char> source_buffer(LZ4F_MIN_SIZE_TO_KNOW_HEADER_LENGTH);
  FileImpl::ReadFromOffset(0, source_buffer.data(),
                           LZ4F_MIN_SIZE_TO_KNOW_HEADER_LENGTH);
  return LZ4F_headerSize(source_buffer.data(),
                         LZ4F_MIN_SIZE_TO_KNOW_HEADER_LENGTH);
}

size_t LZ4FileImpl::ConsumeHeader(LZ4F_frameInfo_t* frame_info,
                                  size_t header_size) {
  std::vector<char> source_buffer(header_size);
  FileImpl::ReadFromOffset(0, source_buffer.data(), header_size);
  return LZ4F_getFrameInfo(lz4f_context_, frame_info, source_buffer.data(),
                           &header_size);
}

bool LZ4FileImpl::Decompress(size_t file_size,
                             size_t header_size,
                             size_t max_compressed_buffer_size,
                             size_t source_bytes_hint) {
  std::vector<char> compressed_data(max_compressed_buffer_size);

  char* compressed_buffer = compressed_data.data();
  char* decompressed_buffer = decompressed_data_.data();

  size_t compressed_size_remaining = file_size - header_size;
  size_t decompressed_size_current = 0;

  while (source_bytes_hint != 0) {
    size_t compressed_buffer_size =
        std::min(source_bytes_hint, max_compressed_buffer_size);
    if (!FileImpl::ReadFromOffset(file_size - compressed_size_remaining,
                                  compressed_data.data(),
                                  compressed_buffer_size)) {
      decompressed_data_.resize(0);
      return false;
    }

    size_t compressed_buffer_offset = 0;

    compressed_buffer = compressed_data.data();

    while (source_bytes_hint != 0 &&
           compressed_buffer_offset < compressed_buffer_size) {
      size_t compressed = compressed_buffer_size - compressed_buffer_offset;
      size_t decompressed =
          decompressed_data_.size() - decompressed_size_current;

      source_bytes_hint =
          LZ4F_decompress(lz4f_context_, decompressed_buffer, &decompressed,
                          compressed_buffer, &compressed, nullptr);

      if (LZ4F_isError(source_bytes_hint)) {
        SB_LOG(ERROR) << LZ4F_getErrorName(source_bytes_hint);
        LZ4F_resetDecompressionContext(lz4f_context_);
        decompressed_data_.resize(0);
        return false;
      }

      compressed_size_remaining -= compressed;
      decompressed_size_current += decompressed;

      compressed_buffer_offset += compressed;
      compressed_buffer += compressed;

      decompressed_buffer += decompressed;
    }
  }
  return true;
}

bool LZ4FileImpl::ReadFromOffset(int64_t offset, char* buffer, int size) {
  SB_DCHECK(lz4f_context_);

  if ((offset < 0) || (offset + size >= decompressed_data_.size())) {
    return false;
  }
  memcpy(buffer, decompressed_data_.data() + offset, size);
  return true;
}

}  // namespace elf_loader
}  // namespace starboard
