/*
 * Copyright (C) 2021 The Android Open Source Project
 *
 * 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 "lz4_legacy.h"

#include <fcntl.h>
#include <sys/stat.h>

#include <vector>

#include <android-base/file.h>
#include <android-base/result.h>
#include <android-base/unique_fd.h>
#include <lz4.h>
#include <storage_literals/storage_literals.h>

using android::base::ErrnoError;
using android::base::Error;
using android::base::ReadFully;
using android::base::unique_fd;
using android::base::WriteFully;
using android::storage_literals::operator""_MiB;

namespace android {

android::base::Result<void> Lz4DecompressLegacy(const char* input,
                                                const char* output) {
  constexpr uint32_t lz4_legacy_magic = 0x184C2102;
  constexpr auto lz4_legacy_block_size = 8_MiB;

  unique_fd ifd(TEMP_FAILURE_RETRY(open(input, O_RDONLY | O_CLOEXEC)));
  unique_fd ofd(TEMP_FAILURE_RETRY(
      open(output, O_WRONLY | O_CREAT | O_CLOEXEC | O_TRUNC, 0640)));

  uint32_t magic;
  if (!ReadFully(ifd, &magic, sizeof(magic))) {
    return ErrnoError() << "read magic";
  }
  // Android is little-endian. No need to convert magic.
  if (magic != lz4_legacy_magic) {
    return Error() << "magic is " << std::hex << magic << " but expected "
                   << lz4_legacy_magic;
  }

  std::vector<char> ibuf(LZ4_compressBound(lz4_legacy_block_size));
  std::vector<char> obuf(lz4_legacy_block_size);

  while (true) {
    uint32_t block_size;
    ssize_t read_bytes =
        TEMP_FAILURE_RETRY(read(ifd.get(), &block_size, sizeof(block_size)));
    if (read_bytes == 0) break;
    if (read_bytes < 0) {
      return ErrnoError() << "read block size";
    }
    if (static_cast<size_t>(read_bytes) != sizeof(block_size)) {
      return Error() << "Cannot read " << sizeof(block_size)
                     << " bytes for block size";
    }

    // Android is little-endian. No need to convert block_size.
    if (block_size == lz4_legacy_magic) {
      return Error() << "Found another lz4 compressed stream";
    }
    if (block_size > ibuf.size()) {
      return Error() << "Block size is " << block_size
                     << " but compress bound is " << ibuf.size();
    }

    if (!ReadFully(ifd, ibuf.data(), block_size)) {
      return ErrnoError() << "read " << block_size << " bytes";
    }

    int decoded_size =
        LZ4_decompress_safe(ibuf.data(), obuf.data(), block_size, obuf.size());
    if (decoded_size < 0) {
      return Error() << "LZ4_decompress_safe returns " << decoded_size;
    }

    if (!WriteFully(ofd, obuf.data(), decoded_size)) {
      return ErrnoError() << "write " << decoded_size << " bytes";
    }
  }

  return {};
}
}  // namespace android
