/*
 * 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 "ziparchive/zip_archive.h"

#include <android-base/test_utils.h>
#include <gtest/gtest.h>
#include <time.h>
#include <memory>
#include <vector>

static ::testing::AssertionResult AssertFileEntryContentsEq(const std::string& expected,
                                                            ZipArchiveHandle handle,
                                                            ZipEntry* zip_entry);

struct zipwriter : public ::testing::Test {
  TemporaryFile* temp_file_;
  int fd_;
  FILE* file_;

  void SetUp() override {
    temp_file_ = new TemporaryFile();
    fd_ = temp_file_->fd;
    file_ = fdopen(fd_, "w");
    ASSERT_NE(file_, nullptr);
  }

  void TearDown() override {
    fclose(file_);
    delete temp_file_;
  }
};

TEST_F(zipwriter, WriteUncompressedZipWithOneFile) {
  ZipWriter writer(file_);

  const char* expected = "hello";

  ASSERT_EQ(0, writer.StartEntry("file.txt", 0));
  ASSERT_EQ(0, writer.WriteBytes("he", 2));
  ASSERT_EQ(0, writer.WriteBytes("llo", 3));
  ASSERT_EQ(0, writer.FinishEntry());
  ASSERT_EQ(0, writer.Finish());

  ASSERT_GE(0, lseek(fd_, 0, SEEK_SET));

  ZipArchiveHandle handle;
  ASSERT_EQ(0, OpenArchiveFd(fd_, "temp", &handle, false));

  ZipEntry data;
  ASSERT_EQ(0, FindEntry(handle, "file.txt", &data));
  EXPECT_EQ(kCompressStored, data.method);
  EXPECT_EQ(0u, data.has_data_descriptor);
  EXPECT_EQ(strlen(expected), data.compressed_length);
  ASSERT_EQ(strlen(expected), data.uncompressed_length);
  ASSERT_TRUE(AssertFileEntryContentsEq(expected, handle, &data));

  CloseArchive(handle);
}

TEST_F(zipwriter, WriteUncompressedZipWithMultipleFiles) {
  ZipWriter writer(file_);

  ASSERT_EQ(0, writer.StartEntry("file.txt", 0));
  ASSERT_EQ(0, writer.WriteBytes("he", 2));
  ASSERT_EQ(0, writer.FinishEntry());

  ASSERT_EQ(0, writer.StartEntry("file/file.txt", 0));
  ASSERT_EQ(0, writer.WriteBytes("llo", 3));
  ASSERT_EQ(0, writer.FinishEntry());

  ASSERT_EQ(0, writer.StartEntry("file/file2.txt", 0));
  ASSERT_EQ(0, writer.FinishEntry());

  ASSERT_EQ(0, writer.Finish());

  ASSERT_GE(0, lseek(fd_, 0, SEEK_SET));

  ZipArchiveHandle handle;
  ASSERT_EQ(0, OpenArchiveFd(fd_, "temp", &handle, false));

  ZipEntry data;

  ASSERT_EQ(0, FindEntry(handle, "file.txt", &data));
  EXPECT_EQ(kCompressStored, data.method);
  EXPECT_EQ(2u, data.compressed_length);
  ASSERT_EQ(2u, data.uncompressed_length);
  ASSERT_TRUE(AssertFileEntryContentsEq("he", handle, &data));

  ASSERT_EQ(0, FindEntry(handle, "file/file.txt", &data));
  EXPECT_EQ(kCompressStored, data.method);
  EXPECT_EQ(3u, data.compressed_length);
  ASSERT_EQ(3u, data.uncompressed_length);
  ASSERT_TRUE(AssertFileEntryContentsEq("llo", handle, &data));

  ASSERT_EQ(0, FindEntry(handle, "file/file2.txt", &data));
  EXPECT_EQ(kCompressStored, data.method);
  EXPECT_EQ(0u, data.compressed_length);
  EXPECT_EQ(0u, data.uncompressed_length);

  CloseArchive(handle);
}

TEST_F(zipwriter, WriteUncompressedZipFileWithAlignedFlag) {
  ZipWriter writer(file_);

  ASSERT_EQ(0, writer.StartEntry("align.txt", ZipWriter::kAlign32));
  ASSERT_EQ(0, writer.WriteBytes("he", 2));
  ASSERT_EQ(0, writer.FinishEntry());
  ASSERT_EQ(0, writer.Finish());

  ASSERT_GE(0, lseek(fd_, 0, SEEK_SET));

  ZipArchiveHandle handle;
  ASSERT_EQ(0, OpenArchiveFd(fd_, "temp", &handle, false));

  ZipEntry data;
  ASSERT_EQ(0, FindEntry(handle, "align.txt", &data));
  EXPECT_EQ(0, data.offset & 0x03);

  CloseArchive(handle);
}

static struct tm MakeTm() {
  struct tm tm;
  memset(&tm, 0, sizeof(struct tm));
  tm.tm_year = 2001 - 1900;
  tm.tm_mon = 1;
  tm.tm_mday = 12;
  tm.tm_hour = 18;
  tm.tm_min = 30;
  tm.tm_sec = 20;
  return tm;
}

TEST_F(zipwriter, WriteUncompressedZipFileWithAlignedFlagAndTime) {
  ZipWriter writer(file_);

  struct tm tm = MakeTm();
  time_t time = mktime(&tm);
  ASSERT_EQ(0, writer.StartEntryWithTime("align.txt", ZipWriter::kAlign32, time));
  ASSERT_EQ(0, writer.WriteBytes("he", 2));
  ASSERT_EQ(0, writer.FinishEntry());
  ASSERT_EQ(0, writer.Finish());

  ASSERT_GE(0, lseek(fd_, 0, SEEK_SET));

  ZipArchiveHandle handle;
  ASSERT_EQ(0, OpenArchiveFd(fd_, "temp", &handle, false));

  ZipEntry data;
  ASSERT_EQ(0, FindEntry(handle, "align.txt", &data));
  EXPECT_EQ(0, data.offset & 0x03);

  struct tm mod = data.GetModificationTime();
  EXPECT_EQ(tm.tm_sec, mod.tm_sec);
  EXPECT_EQ(tm.tm_min, mod.tm_min);
  EXPECT_EQ(tm.tm_hour, mod.tm_hour);
  EXPECT_EQ(tm.tm_mday, mod.tm_mday);
  EXPECT_EQ(tm.tm_mon, mod.tm_mon);
  EXPECT_EQ(tm.tm_year, mod.tm_year);

  CloseArchive(handle);
}

TEST_F(zipwriter, WriteUncompressedZipFileWithAlignedValue) {
  ZipWriter writer(file_);

  ASSERT_EQ(0, writer.StartAlignedEntry("align.txt", 0, 4096));
  ASSERT_EQ(0, writer.WriteBytes("he", 2));
  ASSERT_EQ(0, writer.FinishEntry());
  ASSERT_EQ(0, writer.Finish());

  ASSERT_GE(0, lseek(fd_, 0, SEEK_SET));

  ZipArchiveHandle handle;
  ASSERT_EQ(0, OpenArchiveFd(fd_, "temp", &handle, false));

  ZipEntry data;
  ASSERT_EQ(0, FindEntry(handle, "align.txt", &data));
  EXPECT_EQ(0, data.offset & 0xfff);

  CloseArchive(handle);
}

TEST_F(zipwriter, WriteUncompressedZipFileWithAlignedValueAndTime) {
  ZipWriter writer(file_);

  struct tm tm = MakeTm();
  time_t time = mktime(&tm);
  ASSERT_EQ(0, writer.StartAlignedEntryWithTime("align.txt", 0, time, 4096));
  ASSERT_EQ(0, writer.WriteBytes("he", 2));
  ASSERT_EQ(0, writer.FinishEntry());
  ASSERT_EQ(0, writer.Finish());

  ASSERT_GE(0, lseek(fd_, 0, SEEK_SET));

  ZipArchiveHandle handle;
  ASSERT_EQ(0, OpenArchiveFd(fd_, "temp", &handle, false));

  ZipEntry data;
  ASSERT_EQ(0, FindEntry(handle, "align.txt", &data));
  EXPECT_EQ(0, data.offset & 0xfff);

  struct tm mod = data.GetModificationTime();
  EXPECT_EQ(tm.tm_sec, mod.tm_sec);
  EXPECT_EQ(tm.tm_min, mod.tm_min);
  EXPECT_EQ(tm.tm_hour, mod.tm_hour);
  EXPECT_EQ(tm.tm_mday, mod.tm_mday);
  EXPECT_EQ(tm.tm_mon, mod.tm_mon);
  EXPECT_EQ(tm.tm_year, mod.tm_year);

  CloseArchive(handle);
}

TEST_F(zipwriter, WriteCompressedZipWithOneFile) {
  ZipWriter writer(file_);

  ASSERT_EQ(0, writer.StartEntry("file.txt", ZipWriter::kCompress));
  ASSERT_EQ(0, writer.WriteBytes("helo", 4));
  ASSERT_EQ(0, writer.FinishEntry());
  ASSERT_EQ(0, writer.Finish());

  ASSERT_GE(0, lseek(fd_, 0, SEEK_SET));

  ZipArchiveHandle handle;
  ASSERT_EQ(0, OpenArchiveFd(fd_, "temp", &handle, false));

  ZipEntry data;
  ASSERT_EQ(0, FindEntry(handle, "file.txt", &data));
  EXPECT_EQ(kCompressDeflated, data.method);
  ASSERT_EQ(4u, data.uncompressed_length);
  ASSERT_TRUE(AssertFileEntryContentsEq("helo", handle, &data));

  CloseArchive(handle);
}

TEST_F(zipwriter, WriteCompressedZipFlushFull) {
  // This exact data will cause the Finish() to require multiple calls
  // to deflate() because the ZipWriter buffer isn't big enough to hold
  // the entire compressed data buffer.
  constexpr size_t kBufSize = 10000000;
  std::vector<uint8_t> buffer(kBufSize);
  size_t prev = 1;
  for (size_t i = 0; i < kBufSize; i++) {
    buffer[i] = static_cast<uint8_t>(i + prev);
    prev = i;
  }

  ZipWriter writer(file_);
  ASSERT_EQ(0, writer.StartEntry("file.txt", ZipWriter::kCompress));
  ASSERT_EQ(0, writer.WriteBytes(buffer.data(), buffer.size()));
  ASSERT_EQ(0, writer.FinishEntry());
  ASSERT_EQ(0, writer.Finish());

  ASSERT_GE(0, lseek(fd_, 0, SEEK_SET));

  ZipArchiveHandle handle;
  ASSERT_EQ(0, OpenArchiveFd(fd_, "temp", &handle, false));

  ZipEntry data;
  ASSERT_EQ(0, FindEntry(handle, "file.txt", &data));
  EXPECT_EQ(kCompressDeflated, data.method);
  EXPECT_EQ(kBufSize, data.uncompressed_length);

  std::vector<uint8_t> decompress(kBufSize);
  memset(decompress.data(), 0, kBufSize);
  ASSERT_EQ(0, ExtractToMemory(handle, &data, decompress.data(),
                               static_cast<uint32_t>(decompress.size())));
  EXPECT_EQ(0, memcmp(decompress.data(), buffer.data(), kBufSize))
      << "Input buffer and output buffer are different.";

  CloseArchive(handle);
}

TEST_F(zipwriter, CheckStartEntryErrors) {
  ZipWriter writer(file_);

  ASSERT_EQ(-5, writer.StartAlignedEntry("align.txt", ZipWriter::kAlign32, 4096));
  ASSERT_EQ(-6, writer.StartAlignedEntry("align.txt", 0, 3));
}

TEST_F(zipwriter, BackupRemovesTheLastFile) {
  ZipWriter writer(file_);

  const char* kKeepThis = "keep this";
  const char* kDropThis = "drop this";
  const char* kReplaceWithThis = "replace with this";

  ZipWriter::FileEntry entry;
  EXPECT_LT(writer.GetLastEntry(&entry), 0);

  ASSERT_EQ(0, writer.StartEntry("keep.txt", 0));
  ASSERT_EQ(0, writer.WriteBytes(kKeepThis, strlen(kKeepThis)));
  ASSERT_EQ(0, writer.FinishEntry());

  ASSERT_EQ(0, writer.GetLastEntry(&entry));
  EXPECT_EQ("keep.txt", entry.path);

  ASSERT_EQ(0, writer.StartEntry("drop.txt", 0));
  ASSERT_EQ(0, writer.WriteBytes(kDropThis, strlen(kDropThis)));
  ASSERT_EQ(0, writer.FinishEntry());

  ASSERT_EQ(0, writer.GetLastEntry(&entry));
  EXPECT_EQ("drop.txt", entry.path);

  ASSERT_EQ(0, writer.DiscardLastEntry());

  ASSERT_EQ(0, writer.GetLastEntry(&entry));
  EXPECT_EQ("keep.txt", entry.path);

  ASSERT_EQ(0, writer.StartEntry("replace.txt", 0));
  ASSERT_EQ(0, writer.WriteBytes(kReplaceWithThis, strlen(kReplaceWithThis)));
  ASSERT_EQ(0, writer.FinishEntry());

  ASSERT_EQ(0, writer.GetLastEntry(&entry));
  EXPECT_EQ("replace.txt", entry.path);

  ASSERT_EQ(0, writer.Finish());

  // Verify that "drop.txt" does not exist.

  ASSERT_GE(0, lseek(fd_, 0, SEEK_SET));

  ZipArchiveHandle handle;
  ASSERT_EQ(0, OpenArchiveFd(fd_, "temp", &handle, false));

  ZipEntry data;
  ASSERT_EQ(0, FindEntry(handle, "keep.txt", &data));
  ASSERT_TRUE(AssertFileEntryContentsEq(kKeepThis, handle, &data));

  ASSERT_NE(0, FindEntry(handle, "drop.txt", &data));

  ASSERT_EQ(0, FindEntry(handle, "replace.txt", &data));
  ASSERT_TRUE(AssertFileEntryContentsEq(kReplaceWithThis, handle, &data));

  CloseArchive(handle);
}

TEST_F(zipwriter, TruncateFileAfterBackup) {
  ZipWriter writer(file_);

  const char* kSmall = "small";

  ASSERT_EQ(0, writer.StartEntry("small.txt", 0));
  ASSERT_EQ(0, writer.WriteBytes(kSmall, strlen(kSmall)));
  ASSERT_EQ(0, writer.FinishEntry());

  ASSERT_EQ(0, writer.StartEntry("large.txt", 0));
  std::vector<uint8_t> data;
  data.resize(1024 * 1024, 0xef);
  ASSERT_EQ(0, writer.WriteBytes(data.data(), data.size()));
  ASSERT_EQ(0, writer.FinishEntry());

  off_t before_len = ftello(file_);

  ZipWriter::FileEntry entry;
  ASSERT_EQ(0, writer.GetLastEntry(&entry));
  ASSERT_EQ(0, writer.DiscardLastEntry());

  ASSERT_EQ(0, writer.Finish());

  off_t after_len = ftello(file_);

  ASSERT_GT(before_len, after_len);
}

static ::testing::AssertionResult AssertFileEntryContentsEq(const std::string& expected,
                                                            ZipArchiveHandle handle,
                                                            ZipEntry* zip_entry) {
  if (expected.size() != zip_entry->uncompressed_length) {
    return ::testing::AssertionFailure()
           << "uncompressed entry size " << zip_entry->uncompressed_length
           << " does not match expected size " << expected.size();
  }

  std::string actual;
  actual.resize(expected.size());

  uint8_t* buffer = reinterpret_cast<uint8_t*>(&*actual.begin());
  if (ExtractToMemory(handle, zip_entry, buffer, static_cast<uint32_t>(actual.size())) != 0) {
    return ::testing::AssertionFailure() << "failed to extract entry";
  }

  if (expected != actual) {
    return ::testing::AssertionFailure() << "actual zip_entry data '" << actual
                                         << "' does not match expected '" << expected << "'";
  }
  return ::testing::AssertionSuccess();
}
