// Copyright 2014 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 "chrome/browser/file_select_helper.h"

#include <Cocoa/Cocoa.h>
#include <sys/stat.h>

#include "base/bind.h"
#include "base/files/file.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/mac/foundation_util.h"
#include "base/task/post_task.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "third_party/zlib/google/zip.h"
#include "ui/shell_dialogs/selected_file_info.h"

namespace {

// Given the |path| of a package, returns the destination that the package
// should be zipped to. Returns an empty path on any errors.
base::FilePath ZipDestination(const base::FilePath& path) {
  base::FilePath dest;

  if (!base::GetTempDir(&dest)) {
    // Couldn't get the temporary directory.
    return base::FilePath();
  }

  // TMPDIR/<bundleID>/zip_cache/<guid>

  NSString* bundleID = [[NSBundle mainBundle] bundleIdentifier];
  dest = dest.Append([bundleID fileSystemRepresentation]);

  dest = dest.Append("zip_cache");

  NSString* guid = [[NSProcessInfo processInfo] globallyUniqueString];
  dest = dest.Append([guid fileSystemRepresentation]);

  return dest;
}

// Returns the path of the package and its components relative to the package's
// parent directory.
std::vector<base::FilePath> RelativePathsForPackage(
    const base::FilePath& package) {
  // Get the base directory.
  base::FilePath base_dir = package.DirName();

  // Add the package as the first relative path.
  std::vector<base::FilePath> relative_paths;
  relative_paths.push_back(package.BaseName());

  // Add the components of the package as relative paths.
  base::FileEnumerator file_enumerator(
      package,
      true /* recursive */,
      base::FileEnumerator::FILES | base::FileEnumerator::DIRECTORIES);
  for (base::FilePath path = file_enumerator.Next(); !path.empty();
       path = file_enumerator.Next()) {
    base::FilePath relative_path;
    bool success = base_dir.AppendRelativePath(path, &relative_path);
    if (success)
      relative_paths.push_back(relative_path);
  }

  return relative_paths;
}

}  // namespace

base::FilePath FileSelectHelper::ZipPackage(const base::FilePath& path) {
  base::FilePath dest(ZipDestination(path));
  if (dest.empty())
    return dest;

  if (!base::CreateDirectory(dest.DirName()))
    return base::FilePath();

  base::File file(dest, base::File::FLAG_CREATE | base::File::FLAG_WRITE);
  if (!file.IsValid())
    return base::FilePath();

  std::vector<base::FilePath> files_to_zip(RelativePathsForPackage(path));
  base::FilePath base_dir = path.DirName();
  bool success = zip::ZipFiles(base_dir, files_to_zip, file.GetPlatformFile());

  int result = -1;
  if (success)
    result = fchmod(file.GetPlatformFile(), S_IRUSR);

  return result >= 0 ? dest : base::FilePath();
}

void FileSelectHelper::ProcessSelectedFilesMac(
    const std::vector<ui::SelectedFileInfo>& files) {
  // Make a mutable copy of the input files.
  std::vector<ui::SelectedFileInfo> files_out(files);
  std::vector<base::FilePath> temporary_files;

  for (auto& file_info : files_out) {
    NSString* filename = base::mac::FilePathToNSString(file_info.local_path);
    BOOL isPackage =
        [[NSWorkspace sharedWorkspace] isFilePackageAtPath:filename];
    if (isPackage && base::DirectoryExists(file_info.local_path)) {
      base::FilePath result = ZipPackage(file_info.local_path);

      if (!result.empty()) {
        temporary_files.push_back(result);
        file_info.local_path = result;
        file_info.file_path = result;
        file_info.display_name.append(".zip");
      }
    }
  }

  base::PostTaskWithTraits(
      FROM_HERE, {content::BrowserThread::UI},
      base::BindOnce(&FileSelectHelper::ProcessSelectedFilesMacOnUIThread,
                     base::Unretained(this), files_out, temporary_files));
}

void FileSelectHelper::ProcessSelectedFilesMacOnUIThread(
    const std::vector<ui::SelectedFileInfo>& files,
    const std::vector<base::FilePath>& temporary_files) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  if (!temporary_files.empty()) {
    temporary_files_.insert(
        temporary_files_.end(), temporary_files.begin(), temporary_files.end());

    // Typically, |temporary_files| are deleted after |web_contents_| is
    // destroyed. If |web_contents_| is already NULL, then the temporary files
    // need to be deleted now.
    if (!web_contents_) {
      DeleteTemporaryFiles();
      RunFileChooserEnd();
      return;
    }
  }

  NotifyRenderFrameHostAndEnd(files);
}
