// Copyright (c) 2012 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/zlib2/google/zip.h"

#include <list>
#include <string>
#include <vector>

#include "base/bind.h"
#include "base/files/file.h"
#include "base/files/file_enumerator.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "base/strings/string_util.h"
#include "build/build_config.h"
#include "third_party/zlib2/google/zip_internal.h"
#include "third_party/zlib2/google/zip_reader.h"
#include "third_party/zlib2/google/zip_writer.h"

namespace zip {
namespace {

bool IsHiddenFile(const base::FilePath& file_path) {
  return file_path.BaseName().value()[0] == '.';
}

bool ExcludeNoFilesFilter(const base::FilePath& file_path) {
  return true;
}

bool ExcludeHiddenFilesFilter(const base::FilePath& file_path) {
  return !IsHiddenFile(file_path);
}

// Creates a directory at |extract_dir|/|entry_path|, including any parents.
bool CreateDirectory(const base::FilePath& extract_dir,
                     const base::FilePath& entry_path) {
  return base::CreateDirectory(extract_dir.Append(entry_path));
}

// Creates a WriterDelegate that can write a file at |extract_dir|/|entry_path|.
std::unique_ptr<WriterDelegate> CreateFilePathWriterDelegate(
    const base::FilePath& extract_dir,
    const base::FilePath& entry_path) {
  return std::make_unique<FilePathWriterDelegate>(
      extract_dir.Append(entry_path));
}

class DirectFileAccessor : public FileAccessor {
 public:
  explicit DirectFileAccessor(base::FilePath src_dir) : src_dir_(src_dir) {}
  ~DirectFileAccessor() override = default;

  std::vector<base::File> OpenFilesForReading(
      const std::vector<base::FilePath>& paths) override {
    std::vector<base::File> files;
    for (const auto& path : paths) {
      base::File file;
      if (base::PathExists(path) && !base::DirectoryExists(path)) {
        file = base::File(path, base::File::FLAG_OPEN | base::File::FLAG_READ);
      }
      files.push_back(std::move(file));
    }
    return files;
  }

  bool DirectoryExists(const base::FilePath& file) override {
    return base::DirectoryExists(file);
  }

  std::vector<DirectoryContentEntry> ListDirectoryContent(
      const base::FilePath& dir) override {
    std::vector<DirectoryContentEntry> files;
    base::FileEnumerator file_enumerator(
        dir, false /* recursive */,
        base::FileEnumerator::FILES | base::FileEnumerator::DIRECTORIES);
    for (base::FilePath path = file_enumerator.Next(); !path.value().empty();
         path = file_enumerator.Next()) {
      files.push_back(DirectoryContentEntry(path, base::DirectoryExists(path)));
    }
    return files;
  }

  base::Time GetLastModifiedTime(const base::FilePath& path) override {
    base::File::Info file_info;
    if (!base::GetFileInfo(path, &file_info)) {
      LOG(ERROR) << "Failed to retrieve file modification time for "
                 << path.value();
    }
    return file_info.last_modified;
  }

 private:
  base::FilePath src_dir_;

  DISALLOW_COPY_AND_ASSIGN(DirectFileAccessor);
};

}  // namespace

ZipParams::ZipParams(const base::FilePath& src_dir,
                     const base::FilePath& dest_file)
    : src_dir_(src_dir),
      dest_file_(dest_file),
      file_accessor_(new DirectFileAccessor(src_dir)) {}

#if defined(OS_POSIX)
// Does not take ownership of |fd|.
ZipParams::ZipParams(const base::FilePath& src_dir, int dest_fd)
    : src_dir_(src_dir),
      dest_fd_(dest_fd),
      file_accessor_(new DirectFileAccessor(src_dir)) {}
#endif

bool Zip(const ZipParams& params) {
  // Using a pointer to avoid copies of a potentially large array.
  const std::vector<base::FilePath>* files_to_add = &params.files_to_zip();
  std::vector<base::FilePath> all_files;
  if (files_to_add->empty()) {
    // Include all files from the src_dir (modulo the src_dir itself and
    // filtered and hidden files).

    files_to_add = &all_files;
    // Using a list so we can call push_back while iterating.
    std::list<FileAccessor::DirectoryContentEntry> entries;
    entries.push_back(FileAccessor::DirectoryContentEntry(
        params.src_dir(), true /* is directory*/));
    const FilterCallback& filter_callback = params.filter_callback();
    for (auto iter = entries.begin(); iter != entries.end(); ++iter) {
      const base::FilePath& entry_path = iter->path;
      if (iter != entries.begin() &&  // Don't filter the root dir.
          ((!params.include_hidden_files() && IsHiddenFile(entry_path)) ||
           (filter_callback && !filter_callback.Run(entry_path)))) {
        continue;
      }

      if (iter != entries.begin()) {  // Exclude the root dir from the ZIP file.
        // Make the path relative for AddEntryToZip.
        base::FilePath relative_path;
        bool success =
            params.src_dir().AppendRelativePath(entry_path, &relative_path);
        DCHECK(success);
        all_files.push_back(relative_path);
      }

      if (iter->is_directory) {
        std::vector<FileAccessor::DirectoryContentEntry> subentries =
            params.file_accessor()->ListDirectoryContent(entry_path);
        entries.insert(entries.end(), subentries.begin(), subentries.end());
      }
    }
  }

  std::unique_ptr<internal::ZipWriter> zip_writer;
#if defined(OS_POSIX)
  if (params.dest_fd() != base::kInvalidPlatformFile) {
    DCHECK(params.dest_file().empty());
    zip_writer = internal::ZipWriter::CreateWithFd(
        params.dest_fd(), params.src_dir(), params.file_accessor());
    if (!zip_writer)
      return false;
  }
#endif
  if (!zip_writer) {
    zip_writer = internal::ZipWriter::Create(
        params.dest_file(), params.src_dir(), params.file_accessor());
    if (!zip_writer)
      return false;
  }
  return zip_writer->WriteEntries(*files_to_add);
}

bool Unzip(const base::FilePath& src_file, const base::FilePath& dest_dir) {
  return UnzipWithFilterCallback(
      src_file, dest_dir, base::BindRepeating(&ExcludeNoFilesFilter), true);
}

bool UnzipWithFilterCallback(const base::FilePath& src_file,
                             const base::FilePath& dest_dir,
                             const FilterCallback& filter_cb,
                             bool log_skipped_files) {
  base::File file(src_file, base::File::FLAG_OPEN | base::File::FLAG_READ);
  if (!file.IsValid()) {
    DLOG(WARNING) << "Failed to open " << src_file.value();
    return false;
  }
#if defined(OS_STARBOARD)
  return UnzipWithFilterAndWriters(
      src_file, base::BindRepeating(&CreateFilePathWriterDelegate, dest_dir),
      base::BindRepeating(&CreateDirectory, dest_dir), filter_cb,
      log_skipped_files);
#else
  return UnzipWithFilterAndWriters(
      file.GetPlatformFile(),
      base::BindRepeating(&CreateFilePathWriterDelegate, dest_dir),
      base::BindRepeating(&CreateDirectory, dest_dir), filter_cb,
      log_skipped_files);
#endif
}

#if defined(OS_STARBOARD)
bool UnzipWithFilterAndWriters(const base::FilePath& src_file,
                               const WriterFactory& writer_factory,
                               const DirectoryCreator& directory_creator,
                               const FilterCallback& filter_cb,
                               bool log_skipped_files) {
  ZipReader reader;
  if (!reader.Open(src_file)) {
    DLOG(WARNING) << "Failed to open src_file " << src_file;
    return false;
  }
  while (reader.HasMore()) {
    if (!reader.OpenCurrentEntryInZip()) {
      DLOG(WARNING) << "Failed to open the current file in zip";
      return false;
    }
    const base::FilePath& entry_path = reader.current_entry_info()->file_path();
    if (reader.current_entry_info()->is_unsafe()) {
      DLOG(WARNING) << "Found an unsafe file in zip " << entry_path;
      return false;
    }
    if (filter_cb.Run(entry_path)) {
      if (reader.current_entry_info()->is_directory()) {
        if (!directory_creator.Run(entry_path))
          return false;
      } else {
        std::unique_ptr<WriterDelegate> writer = writer_factory.Run(entry_path);
        if (!reader.ExtractCurrentEntry(writer.get(),
                                        std::numeric_limits<uint64_t>::max())) {
          DLOG(WARNING) << "Failed to extract " << entry_path;
          return false;
        }
      }
    } else if (log_skipped_files) {
      DLOG(WARNING) << "Skipped file " << entry_path;
    }

    if (!reader.AdvanceToNextEntry()) {
      DLOG(WARNING) << "Failed to advance to the next file";
      return false;
    }
  }
  return true;
}
#else
bool UnzipWithFilterAndWriters(const base::PlatformFile& src_file,
                               const WriterFactory& writer_factory,
                               const DirectoryCreator& directory_creator,
                               const FilterCallback& filter_cb,
                               bool log_skipped_files) {
  ZipReader reader;
  if (!reader.OpenFromPlatformFile(src_file)) {
    DLOG(WARNING) << "Failed to open src_file " << src_file;
    return false;
  }
  while (reader.HasMore()) {
    if (!reader.OpenCurrentEntryInZip()) {
      DLOG(WARNING) << "Failed to open the current file in zip";
      return false;
    }
    const base::FilePath& entry_path = reader.current_entry_info()->file_path();
    if (reader.current_entry_info()->is_unsafe()) {
      DLOG(WARNING) << "Found an unsafe file in zip " << entry_path;
      return false;
    }
    if (filter_cb.Run(entry_path)) {
      if (reader.current_entry_info()->is_directory()) {
        if (!directory_creator.Run(entry_path))
          return false;
      } else {
        std::unique_ptr<WriterDelegate> writer = writer_factory.Run(entry_path);
        if (!reader.ExtractCurrentEntry(writer.get(),
                                        std::numeric_limits<uint64_t>::max())) {
          DLOG(WARNING) << "Failed to extract " << entry_path;
          return false;
        }
      }
    } else if (log_skipped_files) {
      DLOG(WARNING) << "Skipped file " << entry_path;
    }

    if (!reader.AdvanceToNextEntry()) {
      DLOG(WARNING) << "Failed to advance to the next file";
      return false;
    }
  }
  return true;
}
#endif

bool ZipWithFilterCallback(const base::FilePath& src_dir,
                           const base::FilePath& dest_file,
                           const FilterCallback& filter_cb) {
  DCHECK(base::DirectoryExists(src_dir));
  ZipParams params(src_dir, dest_file);
  params.set_filter_callback(filter_cb);
  return Zip(params);
}

bool Zip(const base::FilePath& src_dir, const base::FilePath& dest_file,
         bool include_hidden_files) {
  if (include_hidden_files) {
    return ZipWithFilterCallback(src_dir, dest_file,
                                 base::BindRepeating(&ExcludeNoFilesFilter));
  } else {
    return ZipWithFilterCallback(
        src_dir, dest_file, base::BindRepeating(&ExcludeHiddenFilesFilter));
  }
}

#if defined(OS_POSIX)
bool ZipFiles(const base::FilePath& src_dir,
              const std::vector<base::FilePath>& src_relative_paths,
              int dest_fd) {
  DCHECK(base::DirectoryExists(src_dir));
  ZipParams params(src_dir, dest_fd);
  params.set_files_to_zip(src_relative_paths);
  return Zip(params);
}
#endif  // defined(OS_POSIX)

}  // namespace zip
