/*
 * 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.
 */

#include "ziparchive/zip_writer.h"

#include <cstdio>
#include <sys/param.h>
#include <zlib.h>
#define DEF_MEM_LEVEL 8                // normally in zutil.h?

#include <memory>
#include <vector>

#include "android-base/logging.h"
#include "utils/Compat.h"
#include "utils/Log.h"

#include "entry_name_utils-inl.h"
#include "zip_archive_common.h"

#if !defined(powerof2)
#define powerof2(x) ((((x)-1)&(x))==0)
#endif

/* Zip compression methods we support */
enum {
  kCompressStored     = 0,        // no compression
  kCompressDeflated   = 8,        // standard deflate
};

// Size of the output buffer used for compression.
static const size_t kBufSize = 32768u;

// No error, operation completed successfully.
static const int32_t kNoError = 0;

// The ZipWriter is in a bad state.
static const int32_t kInvalidState = -1;

// There was an IO error while writing to disk.
static const int32_t kIoError = -2;

// The zip entry name was invalid.
static const int32_t kInvalidEntryName = -3;

// An error occurred in zlib.
static const int32_t kZlibError = -4;

// The start aligned function was called with the aligned flag.
static const int32_t kInvalidAlign32Flag = -5;

// The alignment parameter is not a power of 2.
static const int32_t kInvalidAlignment = -6;

static const char* sErrorCodes[] = {
    "Invalid state",
    "IO error",
    "Invalid entry name",
    "Zlib error",
};

const char* ZipWriter::ErrorCodeString(int32_t error_code) {
  if (error_code < 0 && (-error_code) < static_cast<int32_t>(arraysize(sErrorCodes))) {
    return sErrorCodes[-error_code];
  }
  return nullptr;
}

static void DeleteZStream(z_stream* stream) {
  deflateEnd(stream);
  delete stream;
}

ZipWriter::ZipWriter(FILE* f) : file_(f), current_offset_(0), state_(State::kWritingZip),
                                z_stream_(nullptr, DeleteZStream), buffer_(kBufSize) {
}

ZipWriter::ZipWriter(ZipWriter&& writer) : file_(writer.file_),
                                           current_offset_(writer.current_offset_),
                                           state_(writer.state_),
                                           files_(std::move(writer.files_)),
                                           z_stream_(std::move(writer.z_stream_)),
                                           buffer_(std::move(writer.buffer_)){
  writer.file_ = nullptr;
  writer.state_ = State::kError;
}

ZipWriter& ZipWriter::operator=(ZipWriter&& writer) {
  file_ = writer.file_;
  current_offset_ = writer.current_offset_;
  state_ = writer.state_;
  files_ = std::move(writer.files_);
  z_stream_ = std::move(writer.z_stream_);
  buffer_ = std::move(writer.buffer_);
  writer.file_ = nullptr;
  writer.state_ = State::kError;
  return *this;
}

int32_t ZipWriter::HandleError(int32_t error_code) {
  state_ = State::kError;
  z_stream_.reset();
  return error_code;
}

int32_t ZipWriter::StartEntry(const char* path, size_t flags) {
  uint32_t alignment = 0;
  if (flags & kAlign32) {
    flags &= ~kAlign32;
    alignment = 4;
  }
  return StartAlignedEntryWithTime(path, flags, time_t(), alignment);
}

int32_t ZipWriter::StartAlignedEntry(const char* path, size_t flags, uint32_t alignment) {
  return StartAlignedEntryWithTime(path, flags, time_t(), alignment);
}

int32_t ZipWriter::StartEntryWithTime(const char* path, size_t flags, time_t time) {
  uint32_t alignment = 0;
  if (flags & kAlign32) {
    flags &= ~kAlign32;
    alignment = 4;
  }
  return StartAlignedEntryWithTime(path, flags, time, alignment);
}

static void ExtractTimeAndDate(time_t when, uint16_t* out_time, uint16_t* out_date) {
  /* round up to an even number of seconds */
  when = static_cast<time_t>((static_cast<unsigned long>(when) + 1) & (~1));

  struct tm* ptm;
#if !defined(_WIN32)
    struct tm tm_result;
    ptm = localtime_r(&when, &tm_result);
#else
    ptm = localtime(&when);
#endif

  int year = ptm->tm_year;
  if (year < 80) {
    year = 80;
  }

  *out_date = (year - 80) << 9 | (ptm->tm_mon + 1) << 5 | ptm->tm_mday;
  *out_time = ptm->tm_hour << 11 | ptm->tm_min << 5 | ptm->tm_sec >> 1;
}

int32_t ZipWriter::StartAlignedEntryWithTime(const char* path, size_t flags,
                                             time_t time, uint32_t alignment) {
  if (state_ != State::kWritingZip) {
    return kInvalidState;
  }

  if (flags & kAlign32) {
    return kInvalidAlign32Flag;
  }

  if (powerof2(alignment) == 0) {
    return kInvalidAlignment;
  }

  current_file_entry_ = {};
  current_file_entry_.path = path;
  current_file_entry_.local_file_header_offset = current_offset_;

  if (!IsValidEntryName(reinterpret_cast<const uint8_t*>(current_file_entry_.path.data()),
                        current_file_entry_.path.size())) {
    return kInvalidEntryName;
  }

  LocalFileHeader header = {};
  header.lfh_signature = LocalFileHeader::kSignature;

  // Set this flag to denote that a DataDescriptor struct will appear after the data,
  // containing the crc and size fields.
  header.gpb_flags |= kGPBDDFlagMask;

  if (flags & ZipWriter::kCompress) {
    current_file_entry_.compression_method = kCompressDeflated;

    int32_t result = PrepareDeflate();
    if (result != kNoError) {
      return result;
    }
  } else {
    current_file_entry_.compression_method = kCompressStored;
  }
  header.compression_method = current_file_entry_.compression_method;

  ExtractTimeAndDate(time, &current_file_entry_.last_mod_time, &current_file_entry_.last_mod_date);
  header.last_mod_time = current_file_entry_.last_mod_time;
  header.last_mod_date = current_file_entry_.last_mod_date;

  header.file_name_length = current_file_entry_.path.size();

  off64_t offset = current_offset_ + sizeof(header) + current_file_entry_.path.size();
  std::vector<char> zero_padding;
  if (alignment != 0 && (offset & (alignment - 1))) {
    // Pad the extra field so the data will be aligned.
    uint16_t padding = alignment - (offset % alignment);
    header.extra_field_length = padding;
    offset += padding;
    zero_padding.resize(padding);
    memset(zero_padding.data(), 0, zero_padding.size());
  }

  if (fwrite(&header, sizeof(header), 1, file_) != 1) {
    return HandleError(kIoError);
  }

  if (fwrite(path, sizeof(*path), current_file_entry_.path.size(), file_)
      != current_file_entry_.path.size()) {
    return HandleError(kIoError);
  }

  if (header.extra_field_length != 0 &&
      fwrite(zero_padding.data(), 1, header.extra_field_length, file_)
      != header.extra_field_length) {
    return HandleError(kIoError);
  }

  current_offset_ = offset;
  state_ = State::kWritingEntry;
  return kNoError;
}

int32_t ZipWriter::DiscardLastEntry() {
  if (state_ != State::kWritingZip || files_.empty()) {
    return kInvalidState;
  }

  FileEntry& last_entry = files_.back();
  current_offset_ = last_entry.local_file_header_offset;
  if (fseeko(file_, current_offset_, SEEK_SET) != 0) {
    return HandleError(kIoError);
  }
  files_.pop_back();
  return kNoError;
}

int32_t ZipWriter::GetLastEntry(FileEntry* out_entry) {
  CHECK(out_entry != nullptr);

  if (files_.empty()) {
    return kInvalidState;
  }
  *out_entry = files_.back();
  return kNoError;
}

int32_t ZipWriter::PrepareDeflate() {
  CHECK(state_ == State::kWritingZip);

  // Initialize the z_stream for compression.
  z_stream_ = std::unique_ptr<z_stream, void(*)(z_stream*)>(new z_stream(), DeleteZStream);

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wold-style-cast"
  int zerr = deflateInit2(z_stream_.get(), Z_BEST_COMPRESSION, Z_DEFLATED, -MAX_WBITS,
                          DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY);
#pragma GCC diagnostic pop

  if (zerr != Z_OK) {
    if (zerr == Z_VERSION_ERROR) {
      ALOGE("Installed zlib is not compatible with linked version (%s)", ZLIB_VERSION);
      return HandleError(kZlibError);
    } else {
      ALOGE("deflateInit2 failed (zerr=%d)", zerr);
      return HandleError(kZlibError);
    }
  }

  z_stream_->next_out = buffer_.data();
  z_stream_->avail_out = buffer_.size();
  return kNoError;
}

int32_t ZipWriter::WriteBytes(const void* data, size_t len) {
  if (state_ != State::kWritingEntry) {
    return HandleError(kInvalidState);
  }

  int32_t result = kNoError;
  if (current_file_entry_.compression_method & kCompressDeflated) {
    result = CompressBytes(&current_file_entry_, data, len);
  } else {
    result = StoreBytes(&current_file_entry_, data, len);
  }

  if (result != kNoError) {
    return result;
  }

  current_file_entry_.crc32 = crc32(current_file_entry_.crc32,
                                    reinterpret_cast<const Bytef*>(data), len);
  current_file_entry_.uncompressed_size += len;
  return kNoError;
}

int32_t ZipWriter::StoreBytes(FileEntry* file, const void* data, size_t len) {
  CHECK(state_ == State::kWritingEntry);

  if (fwrite(data, 1, len, file_) != len) {
    return HandleError(kIoError);
  }
  file->compressed_size += len;
  current_offset_ += len;
  return kNoError;
}

int32_t ZipWriter::CompressBytes(FileEntry* file, const void* data, size_t len) {
  CHECK(state_ == State::kWritingEntry);
  CHECK(z_stream_);
  CHECK(z_stream_->next_out != nullptr);
  CHECK(z_stream_->avail_out != 0);

  // Prepare the input.
  z_stream_->next_in = reinterpret_cast<const uint8_t*>(data);
  z_stream_->avail_in = len;

  while (z_stream_->avail_in > 0) {
    // We have more data to compress.
    int zerr = deflate(z_stream_.get(), Z_NO_FLUSH);
    if (zerr != Z_OK) {
      return HandleError(kZlibError);
    }

    if (z_stream_->avail_out == 0) {
      // The output is full, let's write it to disk.
      size_t write_bytes = z_stream_->next_out - buffer_.data();
      if (fwrite(buffer_.data(), 1, write_bytes, file_) != write_bytes) {
        return HandleError(kIoError);
      }
      file->compressed_size += write_bytes;
      current_offset_ += write_bytes;

      // Reset the output buffer for the next input.
      z_stream_->next_out = buffer_.data();
      z_stream_->avail_out = buffer_.size();
    }
  }
  return kNoError;
}

int32_t ZipWriter::FlushCompressedBytes(FileEntry* file) {
  CHECK(state_ == State::kWritingEntry);
  CHECK(z_stream_);
  CHECK(z_stream_->next_out != nullptr);
  CHECK(z_stream_->avail_out != 0);

  // Keep deflating while there isn't enough space in the buffer to
  // to complete the compress.
  int zerr;
  while ((zerr = deflate(z_stream_.get(), Z_FINISH)) == Z_OK) {
    CHECK(z_stream_->avail_out == 0);
    size_t write_bytes = z_stream_->next_out - buffer_.data();
    if (fwrite(buffer_.data(), 1, write_bytes, file_) != write_bytes) {
      return HandleError(kIoError);
    }
    file->compressed_size += write_bytes;
    current_offset_ += write_bytes;

    z_stream_->next_out = buffer_.data();
    z_stream_->avail_out = buffer_.size();
  }
  if (zerr != Z_STREAM_END) {
    return HandleError(kZlibError);
  }

  size_t write_bytes = z_stream_->next_out - buffer_.data();
  if (write_bytes != 0) {
    if (fwrite(buffer_.data(), 1, write_bytes, file_) != write_bytes) {
      return HandleError(kIoError);
    }
    file->compressed_size += write_bytes;
    current_offset_ += write_bytes;
  }
  z_stream_.reset();
  return kNoError;
}

int32_t ZipWriter::FinishEntry() {
  if (state_ != State::kWritingEntry) {
    return kInvalidState;
  }

  if (current_file_entry_.compression_method & kCompressDeflated) {
    int32_t result = FlushCompressedBytes(&current_file_entry_);
    if (result != kNoError) {
      return result;
    }
  }

  const uint32_t sig = DataDescriptor::kOptSignature;
  if (fwrite(&sig, sizeof(sig), 1, file_) != 1) {
    state_ = State::kError;
    return kIoError;
  }

  DataDescriptor dd = {};
  dd.crc32 = current_file_entry_.crc32;
  dd.compressed_size = current_file_entry_.compressed_size;
  dd.uncompressed_size = current_file_entry_.uncompressed_size;
  if (fwrite(&dd, sizeof(dd), 1, file_) != 1) {
    return HandleError(kIoError);
  }

  files_.emplace_back(std::move(current_file_entry_));

  current_offset_ += sizeof(DataDescriptor::kOptSignature) + sizeof(dd);
  state_ = State::kWritingZip;
  return kNoError;
}

int32_t ZipWriter::Finish() {
  if (state_ != State::kWritingZip) {
    return kInvalidState;
  }

  off64_t startOfCdr = current_offset_;
  for (FileEntry& file : files_) {
    CentralDirectoryRecord cdr = {};
    cdr.record_signature = CentralDirectoryRecord::kSignature;
    cdr.gpb_flags |= kGPBDDFlagMask;
    cdr.compression_method = file.compression_method;
    cdr.last_mod_time = file.last_mod_time;
    cdr.last_mod_date = file.last_mod_date;
    cdr.crc32 = file.crc32;
    cdr.compressed_size = file.compressed_size;
    cdr.uncompressed_size = file.uncompressed_size;
    cdr.file_name_length = file.path.size();
    cdr.local_file_header_offset = file.local_file_header_offset;
    if (fwrite(&cdr, sizeof(cdr), 1, file_) != 1) {
      return HandleError(kIoError);
    }

    if (fwrite(file.path.data(), 1, file.path.size(), file_) != file.path.size()) {
      return HandleError(kIoError);
    }

    current_offset_ += sizeof(cdr) + file.path.size();
  }

  EocdRecord er = {};
  er.eocd_signature = EocdRecord::kSignature;
  er.disk_num = 0;
  er.cd_start_disk = 0;
  er.num_records_on_disk = files_.size();
  er.num_records = files_.size();
  er.cd_size = current_offset_ - startOfCdr;
  er.cd_start_offset = startOfCdr;

  if (fwrite(&er, sizeof(er), 1, file_) != 1) {
    return HandleError(kIoError);
  }

  current_offset_ += sizeof(er);

  // Since we can BackUp() and potentially finish writing at an offset less than one we had
  // already written at, we must truncate the file.

  if (ftruncate64(fileno(file_), current_offset_) != 0) {
    return HandleError(kIoError);
  }

  if (fflush(file_) != 0) {
    return HandleError(kIoError);
  }

  state_ = State::kDone;
  return kNoError;
}
