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

#include "ui/shell_dialogs/execute_select_file_win.h"

#include <shlobj.h>
#include <wrl/client.h>

#include <memory>

#include "base/check.h"
#include "base/feature_list.h"
#include "base/files/file.h"
#include "base/files/file_util.h"
#include "base/functional/callback.h"
#include "base/strings/string_util.h"
#include "base/threading/hang_watcher.h"
#include "base/win/com_init_util.h"
#include "base/win/registry.h"
#include "base/win/scoped_co_mem.h"
#include "base/win/shortcut.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/shell_dialogs/auto_close_dialog_event_handler_win.h"
#include "ui/shell_dialogs/base_shell_dialog_win.h"
#include "ui/shell_dialogs/select_file_utils_win.h"
#include "ui/strings/grit/ui_strings.h"

namespace ui {

namespace {

// Stop switch for the AutoCloseDialogEventHandler.
BASE_FEATURE(kAutoCloseFileDialogs, base::FEATURE_ENABLED_BY_DEFAULT);

// RAII wrapper around AutoCloseDialogEventHandler.
class ScopedAutoCloseDialogEventHandler {
 public:
  ScopedAutoCloseDialogEventHandler(HWND owner_window, IFileDialog* file_dialog)
      : file_dialog_(file_dialog) {
    CHECK(file_dialog_);

    if (!owner_window) {
      return;
    }

    if (!base::FeatureList::IsEnabled(kAutoCloseFileDialogs)) {
      return;
    }

    Microsoft::WRL::ComPtr<IFileDialogEvents> dialog_event_handler =
        Microsoft::WRL::Make<AutoCloseDialogEventHandler>(owner_window);
    if (!dialog_event_handler) {
      return;
    }

    file_dialog_->Advise(dialog_event_handler.Get(), &cookie_);
  }

  ~ScopedAutoCloseDialogEventHandler() {
    if (cookie_) {
      file_dialog_->Unadvise(cookie_);
    }
  }

 private:
  Microsoft::WRL::ComPtr<IFileDialog> file_dialog_;
  DWORD cookie_ = 0;
};

// Distinguish directories from regular files.
bool IsDirectory(const base::FilePath& path) {
  base::File::Info file_info;
  return base::GetFileInfo(path, &file_info) ? file_info.is_directory
                                             : path.EndsWithSeparator();
}

// Sets which path is going to be open when the dialog will be shown. If
// |default_path| is not only a directory, also sets the contents of the text
// box equals to the basename of the path.
bool SetDefaultPath(IFileDialog* file_dialog,
                    const base::FilePath& default_path) {
  if (default_path.empty())
    return true;

  base::FilePath default_folder;
  base::FilePath default_file_name;
  if (IsDirectory(default_path)) {
    default_folder = default_path;
  } else {
    default_folder = default_path.DirName();
    std::wstring sanitized = RemoveEnvVarFromFileName<wchar_t>(
        default_path.BaseName().value(), std::wstring(L"%"));
    default_file_name = base::FilePath(sanitized);
  }

  // Do not fail the file dialog operation if the specified folder is invalid.
  Microsoft::WRL::ComPtr<IShellItem> default_folder_shell_item;
  if (SUCCEEDED(SHCreateItemFromParsingName(
          default_folder.value().c_str(), nullptr,
          IID_PPV_ARGS(&default_folder_shell_item)))) {
    if (FAILED(file_dialog->SetFolder(default_folder_shell_item.Get())))
      return false;
  }

  return SUCCEEDED(file_dialog->SetFileName(default_file_name.value().c_str()));
}

// Sets the file extension filters on the dialog.
bool SetFilters(IFileDialog* file_dialog,
                const std::vector<FileFilterSpec>& filter,
                int filter_index) {
  if (filter.empty())
    return true;

  // A COMDLG_FILTERSPEC instance does not own any memory. |filter| must still
  // be alive at the time the dialog is shown.
  std::vector<COMDLG_FILTERSPEC> comdlg_filterspec(filter.size());

  for (size_t i = 0; i < filter.size(); ++i) {
    comdlg_filterspec[i].pszName = base::as_wcstr(filter[i].description);
    comdlg_filterspec[i].pszSpec = base::as_wcstr(filter[i].extension_spec);
  }

  return SUCCEEDED(file_dialog->SetFileTypes(comdlg_filterspec.size(),
                                             comdlg_filterspec.data())) &&
         SUCCEEDED(file_dialog->SetFileTypeIndex(filter_index));
}

// Sets the requested |dialog_options|, making sure to keep the default values
// when not overwritten.
bool SetOptions(IFileDialog* file_dialog, DWORD dialog_options) {
  // First retrieve the default options for a file dialog.
  DWORD options;
  if (FAILED(file_dialog->GetOptions(&options)))
    return false;

  options |= dialog_options;

  return SUCCEEDED(file_dialog->SetOptions(options));
}

// Configures a |file_dialog| object given the specified parameters.
bool ConfigureDialog(IFileDialog* file_dialog,
                     const std::u16string& title,
                     const std::u16string& ok_button_label,
                     const base::FilePath& default_path,
                     const std::vector<FileFilterSpec>& filter,
                     int filter_index,
                     DWORD dialog_options) {
  // Set title.
  if (!title.empty()) {
    if (FAILED(file_dialog->SetTitle(base::as_wcstr(title))))
      return false;
  }

  if (!ok_button_label.empty()) {
    if (FAILED(file_dialog->SetOkButtonLabel(base::as_wcstr(ok_button_label))))
      return false;
  }

  return SetDefaultPath(file_dialog, default_path) &&
         SetOptions(file_dialog, dialog_options) &&
         SetFilters(file_dialog, filter, filter_index);
}

// Prompt the user for location to save a file.
// Callers should provide the filter string, and also a filter index.
// The parameter |index| indicates the initial index of filter description and
// filter pattern for the dialog box. If |index| is zero or greater than the
// number of total filter types, the system uses the first filter in the
// |filter| buffer. |index| is used to specify the initial selected extension,
// and when done contains the extension the user chose. The parameter |path|
// returns the file name which contains the drive designator, path, file name,
// and extension of the user selected file name. |def_ext| is the default
// extension to give to the file if the user did not enter an extension.
bool RunSaveFileDialog(HWND owner,
                       const std::u16string& title,
                       const base::FilePath& default_path,
                       const std::vector<FileFilterSpec>& filter,
                       DWORD dialog_options,
                       const std::wstring& def_ext,
                       int* filter_index,
                       base::FilePath* path) {
  Microsoft::WRL::ComPtr<IFileSaveDialog> file_save_dialog;
  if (FAILED(::CoCreateInstance(CLSID_FileSaveDialog, nullptr,
                                CLSCTX_INPROC_SERVER,
                                IID_PPV_ARGS(&file_save_dialog)))) {
    return false;
  }

  if (!ConfigureDialog(file_save_dialog.Get(), title, std::u16string(),
                       default_path, filter, *filter_index, dialog_options)) {
    return false;
  }

  file_save_dialog->SetDefaultExtension(def_ext.c_str());

  // This handler auto-closes the file dialog if its owner window is closed.
  auto auto_close_dialog_event_handler =
      std::make_unique<ScopedAutoCloseDialogEventHandler>(
          owner, file_save_dialog.Get());

  // Never consider the current scope as hung. The hang watching deadline (if
  // any) is not valid since the user can take unbounded time to choose the
  // file.
  base::HangWatcher::InvalidateActiveExpectations();

  HRESULT hr = file_save_dialog->Show(owner);
  BaseShellDialogImpl::DisableOwner(owner);

  // Remove the event handler regardless of the return value of Show().
  auto_close_dialog_event_handler = nullptr;

  if (FAILED(hr))
    return false;

  UINT file_type_index;
  if (FAILED(file_save_dialog->GetFileTypeIndex(&file_type_index)))
    return false;

  *filter_index = static_cast<int>(file_type_index);

  Microsoft::WRL::ComPtr<IShellItem> result;
  if (FAILED(file_save_dialog->GetResult(&result)))
    return false;

  base::win::ScopedCoMem<wchar_t> display_name;
  if (FAILED(result->GetDisplayName(SIGDN_DESKTOPABSOLUTEPARSING,
                                    &display_name))) {
    return false;
  }

  *path = base::FilePath(display_name.get());
  return true;
}

// Runs an Open file dialog box, with similar semantics for input parameters as
// RunSaveFileDialog.
bool RunOpenFileDialog(HWND owner,
                       const std::u16string& title,
                       const std::u16string& ok_button_label,
                       const base::FilePath& default_path,
                       const std::vector<FileFilterSpec>& filter,
                       DWORD dialog_options,
                       int* filter_index,
                       std::vector<base::FilePath>* paths) {
  Microsoft::WRL::ComPtr<IFileOpenDialog> file_open_dialog;
  if (FAILED(::CoCreateInstance(CLSID_FileOpenDialog, nullptr,
                                CLSCTX_INPROC_SERVER,
                                IID_PPV_ARGS(&file_open_dialog)))) {
    return false;
  }

  // The FOS_FORCEFILESYSTEM option ensures that if the user enters a URL in the
  // "File name" box, it will be downloaded locally and its new file path will
  // be returned by the dialog. This was a default option in the deprecated
  // GetOpenFileName API.
  dialog_options |= FOS_FORCEFILESYSTEM;

  if (!ConfigureDialog(file_open_dialog.Get(), title, ok_button_label,
                       default_path, filter, *filter_index, dialog_options)) {
    return false;
  }

  // This handler auto-closes the file dialog if its owner window is closed.
  auto auto_close_dialog_event_handler =
      std::make_unique<ScopedAutoCloseDialogEventHandler>(
          owner, file_open_dialog.Get());

  // Never consider the current scope as hung. The hang watching deadline (if
  // any) is not valid since the user can take unbounded time to choose the
  // file.
  base::HangWatcher::InvalidateActiveExpectations();

  HRESULT hr = file_open_dialog->Show(owner);
  BaseShellDialogImpl::DisableOwner(owner);

  // Remove the event handler regardless of the return value of Show().
  auto_close_dialog_event_handler = nullptr;

  if (FAILED(hr))
    return false;

  UINT file_type_index;
  if (FAILED(file_open_dialog->GetFileTypeIndex(&file_type_index)))
    return false;

  *filter_index = static_cast<int>(file_type_index);

  Microsoft::WRL::ComPtr<IShellItemArray> selected_items;
  if (FAILED(file_open_dialog->GetResults(&selected_items)))
    return false;

  DWORD result_count;
  if (FAILED(selected_items->GetCount(&result_count)))
    return false;

  DCHECK(result_count == 1 || (dialog_options & FOS_ALLOWMULTISELECT));

  std::vector<base::FilePath> result(result_count);
  for (DWORD i = 0; i < result_count; ++i) {
    Microsoft::WRL::ComPtr<IShellItem> shell_item;
    if (FAILED(selected_items->GetItemAt(i, &shell_item)))
      return false;

    base::win::ScopedCoMem<wchar_t> display_name;
    if (FAILED(shell_item->GetDisplayName(SIGDN_DESKTOPABSOLUTEPARSING,
                                          &display_name))) {
      return false;
    }

    result[i] = base::FilePath(display_name.get());
  }

  // Only modify the out parameter if the enumeration didn't fail.
  *paths = std::move(result);
  return !paths->empty();
}

// Runs a Folder selection dialog box, passes back the selected folder in |path|
// and returns true if the user clicks OK. If the user cancels the dialog box
// the value in |path| is not modified and returns false. Run on the dialog
// thread.
bool ExecuteSelectFolder(HWND owner,
                         SelectFileDialog::Type type,
                         const std::u16string& title,
                         const base::FilePath& default_path,
                         std::vector<base::FilePath>* paths) {
  DCHECK(paths);

  std::u16string new_title = title;
  if (new_title.empty() && type == SelectFileDialog::SELECT_UPLOAD_FOLDER) {
    // If it's for uploading don't use default dialog title to
    // make sure we clearly tell it's for uploading.
    new_title =
        l10n_util::GetStringUTF16(IDS_SELECT_UPLOAD_FOLDER_DIALOG_TITLE);
  }

  std::u16string ok_button_label;
  if (type == SelectFileDialog::SELECT_UPLOAD_FOLDER) {
    ok_button_label = l10n_util::GetStringUTF16(
        IDS_SELECT_UPLOAD_FOLDER_DIALOG_UPLOAD_BUTTON);
  }

  DWORD dialog_options = FOS_PICKFOLDERS;

  std::vector<FileFilterSpec> no_filter;
  int filter_index = 0;

  return RunOpenFileDialog(owner, new_title, ok_button_label, default_path,
                           no_filter, dialog_options, &filter_index, paths);
}

bool ExecuteSelectSingleFile(HWND owner,
                             const std::u16string& title,
                             const base::FilePath& default_path,
                             const std::vector<FileFilterSpec>& filter,
                             int* filter_index,
                             std::vector<base::FilePath>* paths) {
  return RunOpenFileDialog(owner, title, std::u16string(), default_path, filter,
                           0, filter_index, paths);
}

bool ExecuteSelectMultipleFile(HWND owner,
                               const std::u16string& title,
                               const base::FilePath& default_path,
                               const std::vector<FileFilterSpec>& filter,
                               int* filter_index,
                               std::vector<base::FilePath>* paths) {
  DWORD dialog_options = FOS_ALLOWMULTISELECT;
  return RunOpenFileDialog(owner, title, std::u16string(), default_path, filter,
                           dialog_options, filter_index, paths);
}

bool ExecuteSaveFile(HWND owner,
                     const std::u16string& title,
                     const base::FilePath& default_path,
                     const std::vector<FileFilterSpec>& filter,
                     const std::wstring& def_ext,
                     int* filter_index,
                     base::FilePath* path) {
  DCHECK(path);
  // Having an empty filter for a bad user experience. We should always
  // specify a filter when saving.
  DCHECK(!filter.empty());

  DWORD dialog_options = FOS_OVERWRITEPROMPT;

  return RunSaveFileDialog(owner, title, default_path, filter, dialog_options,
                           def_ext, filter_index, path);
}

}  // namespace

void ExecuteSelectFile(
    SelectFileDialog::Type type,
    const std::u16string& title,
    const base::FilePath& default_path,
    const std::vector<FileFilterSpec>& filter,
    int file_type_index,
    const std::wstring& default_extension,
    HWND owner,
    OnSelectFileExecutedCallback on_select_file_executed_callback) {
  base::win::AssertComInitialized();
  std::vector<base::FilePath> paths;
  switch (type) {
    case SelectFileDialog::SELECT_FOLDER:
    case SelectFileDialog::SELECT_UPLOAD_FOLDER:
    case SelectFileDialog::SELECT_EXISTING_FOLDER:
      ExecuteSelectFolder(owner, type, title, default_path, &paths);
      break;
    case SelectFileDialog::SELECT_SAVEAS_FILE: {
      base::FilePath path;
      if (ExecuteSaveFile(owner, title, default_path, filter, default_extension,
                          &file_type_index, &path)) {
        paths.push_back(std::move(path));
      }
      break;
    }
    case SelectFileDialog::SELECT_OPEN_FILE:
      ExecuteSelectSingleFile(owner, title, default_path, filter,
                              &file_type_index, &paths);
      break;
    case SelectFileDialog::SELECT_OPEN_MULTI_FILE:
      ExecuteSelectMultipleFile(owner, title, default_path, filter,
                                &file_type_index, &paths);
      break;
    case SelectFileDialog::SELECT_NONE:
      NOTREACHED();
  }

  std::move(on_select_file_executed_callback).Run(paths, file_type_index);
}

}  // namespace ui
