// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "third_party/zlib/google/zip_writer.h"

#include "base/files/file.h"
#include "base/files/file_util.h"
#include "base/strings/string_util.h"
#include "third_party/zlib/google/zip_internal.h"

namespace zip {
namespace internal {

namespace {

// Numbers of pending entries that trigger writting them to the ZIP file.
constexpr size_t kMaxPendingEntriesCount = 50;

bool AddFileContentToZip(zipFile zip_file,
                         base::File file,
                         const base::FilePath& file_path) {
  int num_bytes;
  char buf[zip::internal::kZipBufSize];
  do {
    num_bytes = file.ReadAtCurrentPos(buf, zip::internal::kZipBufSize);

    if (num_bytes > 0) {
      if (zipWriteInFileInZip(zip_file, buf, num_bytes) != ZIP_OK) {
        DLOG(ERROR) << "Could not write data to zip for path "
                    << file_path.value();
        return false;
      }
    }
  } while (num_bytes > 0);

  return true;
}

bool OpenNewFileEntry(zipFile zip_file,
                      const base::FilePath& path,
                      bool is_directory,
                      base::Time last_modified) {
  std::string str_path = path.AsUTF8Unsafe();
#if defined(OS_WIN)
  base::ReplaceSubstringsAfterOffset(&str_path, 0u, "\\", "/");
#endif
  if (is_directory)
    str_path += "/";

  return zip::internal::ZipOpenNewFileInZip(zip_file, str_path, last_modified);
}

bool CloseNewFileEntry(zipFile zip_file) {
  return zipCloseFileInZip(zip_file) == ZIP_OK;
}

bool AddFileEntryToZip(zipFile zip_file,
                       const base::FilePath& path,
                       base::File file) {
  base::File::Info file_info;
  if (!file.GetInfo(&file_info))
    return false;

  if (!OpenNewFileEntry(zip_file, path, /*is_directory=*/false,
                        file_info.last_modified))
    return false;

  bool success = AddFileContentToZip(zip_file, std::move(file), path);
  if (!CloseNewFileEntry(zip_file))
    return false;

  return success;
}

bool AddDirectoryEntryToZip(zipFile zip_file,
                            const base::FilePath& path,
                            base::Time last_modified) {
  return OpenNewFileEntry(zip_file, path, /*is_directory=*/true,
                          last_modified) &&
         CloseNewFileEntry(zip_file);
}

}  // namespace

#if defined(OS_POSIX)
// static
std::unique_ptr<ZipWriter> ZipWriter::CreateWithFd(
    int zip_file_fd,
    const base::FilePath& root_dir,
    FileAccessor* file_accessor) {
  DCHECK(zip_file_fd != base::kInvalidPlatformFile);
  zipFile zip_file =
      internal::OpenFdForZipping(zip_file_fd, APPEND_STATUS_CREATE);
  if (!zip_file) {
    DLOG(ERROR) << "Couldn't create ZIP file for FD " << zip_file_fd;
    return nullptr;
  }
  return std::unique_ptr<ZipWriter>(
      new ZipWriter(zip_file, root_dir, file_accessor));
}
#endif

// static
std::unique_ptr<ZipWriter> ZipWriter::Create(
    const base::FilePath& zip_file_path,
    const base::FilePath& root_dir,
    FileAccessor* file_accessor) {
  DCHECK(!zip_file_path.empty());
  zipFile zip_file = internal::OpenForZipping(zip_file_path.AsUTF8Unsafe(),
                                              APPEND_STATUS_CREATE);
  if (!zip_file) {
    DLOG(ERROR) << "Couldn't create ZIP file at path " << zip_file_path;
    return nullptr;
  }
  return std::unique_ptr<ZipWriter>(
      new ZipWriter(zip_file, root_dir, file_accessor));
}

ZipWriter::ZipWriter(zipFile zip_file,
                     const base::FilePath& root_dir,
                     FileAccessor* file_accessor)
    : zip_file_(zip_file), root_dir_(root_dir), file_accessor_(file_accessor) {}

ZipWriter::~ZipWriter() {
  DCHECK(pending_entries_.empty());
}

bool ZipWriter::WriteEntries(const std::vector<base::FilePath>& paths) {
  return AddEntries(paths) && Close();
}

bool ZipWriter::AddEntries(const std::vector<base::FilePath>& paths) {
  DCHECK(zip_file_);
  pending_entries_.insert(pending_entries_.end(), paths.begin(), paths.end());
  return FlushEntriesIfNeeded(/*force=*/false);
}

bool ZipWriter::Close() {
  bool success = FlushEntriesIfNeeded(/*force=*/true) &&
                 zipClose(zip_file_, nullptr) == ZIP_OK;
  zip_file_ = nullptr;
  return success;
}

bool ZipWriter::FlushEntriesIfNeeded(bool force) {
  if (pending_entries_.size() < kMaxPendingEntriesCount && !force)
    return true;

  while (pending_entries_.size() >= kMaxPendingEntriesCount ||
         (force && !pending_entries_.empty())) {
    size_t entry_count =
        std::min(pending_entries_.size(), kMaxPendingEntriesCount);
    std::vector<base::FilePath> relative_paths;
    std::vector<base::FilePath> absolute_paths;
    relative_paths.insert(relative_paths.begin(), pending_entries_.begin(),
                          pending_entries_.begin() + entry_count);
    for (auto iter = pending_entries_.begin();
         iter != pending_entries_.begin() + entry_count; ++iter) {
      // The FileAccessor requires absolute paths.
      absolute_paths.push_back(root_dir_.Append(*iter));
    }
    pending_entries_.erase(pending_entries_.begin(),
                           pending_entries_.begin() + entry_count);

    // We don't know which paths are files and which ones are directories, and
    // we want to avoid making a call to file_accessor_ for each entry. Open the
    // files instead, invalid files are returned for directories.
    std::vector<base::File> files =
        file_accessor_->OpenFilesForReading(absolute_paths);
    DCHECK_EQ(files.size(), relative_paths.size());
    for (size_t i = 0; i < files.size(); i++) {
      const base::FilePath& relative_path = relative_paths[i];
      const base::FilePath& absolute_path = absolute_paths[i];
      base::File file = std::move(files[i]);
      if (file.IsValid()) {
        if (!AddFileEntryToZip(zip_file_, relative_path, std::move(file))) {
          LOG(ERROR) << "Failed to write file " << relative_path.value()
                     << " to ZIP file.";
          return false;
        }
      } else {
        // Missing file or directory case.
        base::Time last_modified =
            file_accessor_->GetLastModifiedTime(absolute_path);
// Not all platforms provide a mechanism of retrieving the "last modified"
// timestamp of a file, and thus fail the condition below because the returned
// value would be |0|. For OS_STARBOARD, simply check if the directory exists or
// not and assume the timestamp provided is what is desired.
#if defined(OS_STARBOARD)
        if (!file_accessor_->DirectoryExists(absolute_path)) {
#else
        if (last_modified.is_null()) {
#endif
          LOG(ERROR) << "Failed to write entry " << relative_path.value()
                     << " to ZIP file.";
          return false;
        }
        DCHECK(file_accessor_->DirectoryExists(absolute_path));
        if (!AddDirectoryEntryToZip(zip_file_, relative_path, last_modified)) {
          LOG(ERROR) << "Failed to write directory " << relative_path.value()
                     << " to ZIP file.";
          return false;
        }
      }
    }
  }
  return true;
}

}  // namespace internal
}  // namespace zip
