/*
 * Copyright (C) 2015 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.
 */

#define LOG_TAG "ZIPARCHIVE"

// Read-only stream access to Zip Archive entries.
#include <errno.h>
#include <inttypes.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>

#include <memory>
#include <vector>

#include <android-base/file.h>
#include <android-base/logging.h>
#include <log/log.h>

#include <ziparchive/zip_archive.h>
#include <ziparchive/zip_archive_stream_entry.h>
#include <zlib.h>

#include "zip_archive_private.h"

static constexpr size_t kBufSize = 65535;

bool ZipArchiveStreamEntry::Init(const ZipEntry& entry) {
  crc32_ = entry.crc32;
  offset_ = entry.offset;
  return true;
}

class ZipArchiveStreamEntryUncompressed : public ZipArchiveStreamEntry {
 public:
  explicit ZipArchiveStreamEntryUncompressed(ZipArchiveHandle handle)
      : ZipArchiveStreamEntry(handle) {}
  virtual ~ZipArchiveStreamEntryUncompressed() {}

  const std::vector<uint8_t>* Read() override;

  bool Verify() override;

 protected:
  bool Init(const ZipEntry& entry) override;

  uint32_t length_ = 0u;

 private:
  std::vector<uint8_t> data_;
  uint32_t computed_crc32_ = 0u;
};

bool ZipArchiveStreamEntryUncompressed::Init(const ZipEntry& entry) {
  if (!ZipArchiveStreamEntry::Init(entry)) {
    return false;
  }

  length_ = entry.uncompressed_length;

  data_.resize(kBufSize);
  computed_crc32_ = 0;

  return true;
}

const std::vector<uint8_t>* ZipArchiveStreamEntryUncompressed::Read() {
  // Simple validity check. The vector should *only* be handled by this code. A caller
  // should not const-cast and modify the capacity. This may invalidate next_out.
  //
  // Note: it would be better to store the results of data() across Read calls.
  CHECK_EQ(data_.capacity(), kBufSize);

  if (length_ == 0) {
    return nullptr;
  }

  size_t bytes = (length_ > data_.size()) ? data_.size() : length_;
  ZipArchive* archive = reinterpret_cast<ZipArchive*>(handle_);
  errno = 0;
  if (!archive->mapped_zip.ReadAtOffset(data_.data(), bytes, offset_)) {
    if (errno != 0) {
      ALOGE("Error reading from archive fd: %s", strerror(errno));
    } else {
      ALOGE("Short read of zip file, possibly corrupted zip?");
    }
    length_ = 0;
    return nullptr;
  }

  if (bytes < data_.size()) {
    data_.resize(bytes);
  }
  computed_crc32_ = static_cast<uint32_t>(
      crc32(computed_crc32_, data_.data(), static_cast<uint32_t>(data_.size())));
  length_ -= bytes;
  offset_ += bytes;
  return &data_;
}

bool ZipArchiveStreamEntryUncompressed::Verify() {
  return length_ == 0 && crc32_ == computed_crc32_;
}

class ZipArchiveStreamEntryCompressed : public ZipArchiveStreamEntry {
 public:
  explicit ZipArchiveStreamEntryCompressed(ZipArchiveHandle handle)
      : ZipArchiveStreamEntry(handle) {}
  virtual ~ZipArchiveStreamEntryCompressed();

  const std::vector<uint8_t>* Read() override;

  bool Verify() override;

 protected:
  bool Init(const ZipEntry& entry) override;

 private:
  bool z_stream_init_ = false;
  z_stream z_stream_;
  std::vector<uint8_t> in_;
  std::vector<uint8_t> out_;
  uint32_t uncompressed_length_ = 0u;
  uint32_t compressed_length_ = 0u;
  uint32_t computed_crc32_ = 0u;
};

// This method is using libz macros with old-style-casts
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wold-style-cast"
static inline int zlib_inflateInit2(z_stream* stream, int window_bits) {
  return inflateInit2(stream, window_bits);
}
#pragma GCC diagnostic pop

bool ZipArchiveStreamEntryCompressed::Init(const ZipEntry& entry) {
  if (!ZipArchiveStreamEntry::Init(entry)) {
    return false;
  }

  // Initialize the zlib stream struct.
  memset(&z_stream_, 0, sizeof(z_stream_));
  z_stream_.zalloc = Z_NULL;
  z_stream_.zfree = Z_NULL;
  z_stream_.opaque = Z_NULL;
  z_stream_.next_in = nullptr;
  z_stream_.avail_in = 0;
  z_stream_.avail_out = 0;
  z_stream_.data_type = Z_UNKNOWN;

  // Use the undocumented "negative window bits" feature to tell zlib
  // that there's no zlib header waiting for it.
  int zerr = zlib_inflateInit2(&z_stream_, -MAX_WBITS);
  if (zerr != Z_OK) {
    if (zerr == Z_VERSION_ERROR) {
      ALOGE("Installed zlib is not compatible with linked version (%s)", ZLIB_VERSION);
    } else {
      ALOGE("Call to inflateInit2 failed (zerr=%d)", zerr);
    }

    return false;
  }

  z_stream_init_ = true;

  uncompressed_length_ = entry.uncompressed_length;
  compressed_length_ = entry.compressed_length;

  out_.resize(kBufSize);
  in_.resize(kBufSize);

  computed_crc32_ = 0;

  return true;
}

ZipArchiveStreamEntryCompressed::~ZipArchiveStreamEntryCompressed() {
  if (z_stream_init_) {
    inflateEnd(&z_stream_);
    z_stream_init_ = false;
  }
}

bool ZipArchiveStreamEntryCompressed::Verify() {
  return z_stream_init_ && uncompressed_length_ == 0 && compressed_length_ == 0 &&
         crc32_ == computed_crc32_;
}

const std::vector<uint8_t>* ZipArchiveStreamEntryCompressed::Read() {
  // Simple validity check. The vector should *only* be handled by this code. A caller
  // should not const-cast and modify the capacity. This may invalidate next_out.
  //
  // Note: it would be better to store the results of data() across Read calls.
  CHECK_EQ(out_.capacity(), kBufSize);

  if (z_stream_.avail_out == 0) {
    z_stream_.next_out = out_.data();
    z_stream_.avail_out = static_cast<uint32_t>(out_.size());
    ;
  }

  while (true) {
    if (z_stream_.avail_in == 0) {
      if (compressed_length_ == 0) {
        return nullptr;
      }
      DCHECK_LE(in_.size(), std::numeric_limits<uint32_t>::max());  // Should be buf size = 64k.
      uint32_t bytes = (compressed_length_ > in_.size()) ? static_cast<uint32_t>(in_.size())
                                                         : compressed_length_;
      ZipArchive* archive = reinterpret_cast<ZipArchive*>(handle_);
      errno = 0;
      if (!archive->mapped_zip.ReadAtOffset(in_.data(), bytes, offset_)) {
        if (errno != 0) {
          ALOGE("Error reading from archive fd: %s", strerror(errno));
        } else {
          ALOGE("Short read of zip file, possibly corrupted zip?");
        }
        return nullptr;
      }

      compressed_length_ -= bytes;
      offset_ += bytes;
      z_stream_.next_in = in_.data();
      z_stream_.avail_in = bytes;
    }

    int zerr = inflate(&z_stream_, Z_NO_FLUSH);
    if (zerr != Z_OK && zerr != Z_STREAM_END) {
      ALOGE("inflate zerr=%d (nIn=%p aIn=%u nOut=%p aOut=%u)", zerr, z_stream_.next_in,
            z_stream_.avail_in, z_stream_.next_out, z_stream_.avail_out);
      return nullptr;
    }

    if (z_stream_.avail_out == 0) {
      uncompressed_length_ -= out_.size();
      computed_crc32_ = static_cast<uint32_t>(
          crc32(computed_crc32_, out_.data(), static_cast<uint32_t>(out_.size())));
      return &out_;
    }
    if (zerr == Z_STREAM_END) {
      if (z_stream_.avail_out != 0) {
        // Resize the vector down to the actual size of the data.
        out_.resize(out_.size() - z_stream_.avail_out);
        computed_crc32_ = static_cast<uint32_t>(
            crc32(computed_crc32_, out_.data(), static_cast<uint32_t>(out_.size())));
        uncompressed_length_ -= out_.size();
        return &out_;
      }
      return nullptr;
    }
  }
  return nullptr;
}

class ZipArchiveStreamEntryRawCompressed : public ZipArchiveStreamEntryUncompressed {
 public:
  explicit ZipArchiveStreamEntryRawCompressed(ZipArchiveHandle handle)
      : ZipArchiveStreamEntryUncompressed(handle) {}
  virtual ~ZipArchiveStreamEntryRawCompressed() {}

  bool Verify() override;

 protected:
  bool Init(const ZipEntry& entry) override;
};

bool ZipArchiveStreamEntryRawCompressed::Init(const ZipEntry& entry) {
  if (!ZipArchiveStreamEntryUncompressed::Init(entry)) {
    return false;
  }
  length_ = entry.compressed_length;

  return true;
}

bool ZipArchiveStreamEntryRawCompressed::Verify() {
  return length_ == 0;
}

ZipArchiveStreamEntry* ZipArchiveStreamEntry::Create(ZipArchiveHandle handle,
                                                     const ZipEntry& entry) {
  ZipArchiveStreamEntry* stream = nullptr;
  if (entry.method != kCompressStored) {
    stream = new ZipArchiveStreamEntryCompressed(handle);
  } else {
    stream = new ZipArchiveStreamEntryUncompressed(handle);
  }
  if (stream && !stream->Init(entry)) {
    delete stream;
    stream = nullptr;
  }

  return stream;
}

ZipArchiveStreamEntry* ZipArchiveStreamEntry::CreateRaw(ZipArchiveHandle handle,
                                                        const ZipEntry& entry) {
  ZipArchiveStreamEntry* stream = nullptr;
  if (entry.method == kCompressStored) {
    // Not compressed, don't need to do anything special.
    stream = new ZipArchiveStreamEntryUncompressed(handle);
  } else {
    stream = new ZipArchiveStreamEntryRawCompressed(handle);
  }
  if (stream && !stream->Init(entry)) {
    delete stream;
    stream = nullptr;
  }
  return stream;
}
