// 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 "chrome/browser/platform_util.h"

#include "base/bind.h"
#include "base/command_line.h"
#include "base/files/file_util.h"
#include "base/process/kill.h"
#include "base/process/launch.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task/post_task.h"
#include "base/version.h"
#include "chrome/browser/platform_util_internal.h"
#include "content/public/browser/browser_thread.h"
#include "url/gurl.h"

using content::BrowserThread;

namespace platform_util {

namespace {

const char kNautilusKey[] = "nautilus.desktop";
const char kNautilusKeyExtended[] = "nautilus-folder-handler.desktop";
const char kNautilusCmd[] = "nautilus";
const char kSupportedNautilusVersion[] = "3.0.2";

void RunCommand(const std::string& command,
                const base::FilePath& working_directory,
                const std::string& arg) {
  std::vector<std::string> argv;
  argv.push_back(command);
  argv.push_back(arg);

  base::LaunchOptions options;
  options.current_directory = working_directory;
  options.allow_new_privs = true;
  // xdg-open can fall back on mailcap which eventually might plumb through
  // to a command that needs a terminal.  Set the environment variable telling
  // it that we definitely don't have a terminal available and that it should
  // bring up a new terminal if necessary.  See "man mailcap".
  options.environment["MM_NOTTTY"] = "1";

  // In Google Chrome, we do not let GNOME's bug-buddy intercept our crashes.
  // However, we do not want this environment variable to propagate to external
  // applications. See http://crbug.com/24120
  char* disable_gnome_bug_buddy = getenv("GNOME_DISABLE_CRASH_DIALOG");
  if (disable_gnome_bug_buddy &&
      disable_gnome_bug_buddy == std::string("SET_BY_GOOGLE_CHROME"))
    options.environment["GNOME_DISABLE_CRASH_DIALOG"] = std::string();

  base::Process process = base::LaunchProcess(argv, options);
  if (process.IsValid())
    base::EnsureProcessGetsReaped(std::move(process));
}

void XDGOpen(const base::FilePath& working_directory, const std::string& path) {
  RunCommand("xdg-open", working_directory, path);
}

void XDGEmail(const std::string& email) {
  RunCommand("xdg-email", base::FilePath(), email);
}

void ShowFileInNautilus(const base::FilePath& working_directory,
                        const std::string& path) {
  RunCommand(kNautilusCmd, working_directory, path);
}

std::string GetNautilusVersion() {
  std::string output;
  std::string found_version;

  base::CommandLine nautilus_cl((base::FilePath(kNautilusCmd)));
  nautilus_cl.AppendArg("--version");

  if (base::GetAppOutputAndError(nautilus_cl, &output)) {
    // It is assumed that "nautilus --version" returns something like
    // "GNOME nautilus 3.14.2". First, find the position of the first char of
    // "nautilus " and skip the whole string to get the position of
    // version in the |output| string.
    size_t nautilus_position = output.find("nautilus ");
    size_t version_position = nautilus_position + strlen("nautilus ");
    if (nautilus_position != std::string::npos) {
      found_version = output.substr(version_position);
      base::TrimWhitespaceASCII(found_version,
                                base::TRIM_TRAILING,
                                &found_version);
    }
  }
  return found_version;
}

bool CheckNautilusIsDefault() {
  std::string file_browser;

  base::CommandLine xdg_mime(base::FilePath("xdg-mime"));
  xdg_mime.AppendArg("query");
  xdg_mime.AppendArg("default");
  xdg_mime.AppendArg("inode/directory");

  bool success = base::GetAppOutputAndError(xdg_mime, &file_browser);
  base::TrimWhitespaceASCII(file_browser,
                            base::TRIM_TRAILING,
                            &file_browser);

  if (!success ||
      (file_browser != kNautilusKey && file_browser != kNautilusKeyExtended))
    return false;

  const base::Version supported_version(kSupportedNautilusVersion);
  DCHECK(supported_version.IsValid());
  const base::Version current_version(GetNautilusVersion());
  return current_version.IsValid() && current_version >= supported_version;
}

void ShowItem(Profile* profile,
              const base::FilePath& full_path,
              bool use_nautilus_file_browser) {
  if (use_nautilus_file_browser) {
    OpenItem(profile, full_path, SHOW_ITEM_IN_FOLDER, OpenOperationCallback());
  } else {
    // TODO(estade): It would be nice to be able to select the file in other
    // file managers, but that probably requires extending xdg-open.
    // For now just show the folder for non-Nautilus users.
    OpenItem(profile, full_path.DirName(), OPEN_FOLDER,
             OpenOperationCallback());
  }
}

}  // namespace

namespace internal {

void PlatformOpenVerifiedItem(const base::FilePath& path, OpenItemType type) {
  switch (type) {
    case OPEN_FILE:
      XDGOpen(path.DirName(), path.value());
      break;
    case OPEN_FOLDER:
      // The utility process checks the working directory prior to the
      // invocation of xdg-open by changing the current directory into it. This
      // operation only succeeds if |path| is a directory. Opening "." from
      // there ensures that the target of the operation is a directory.  Note
      // that there remains a TOCTOU race where the directory could be unlinked
      // between the time the utility process changes into the directory and the
      // time the application invoked by xdg-open inspects the path by name.
      XDGOpen(path, ".");
      break;
    case SHOW_ITEM_IN_FOLDER:
      ShowFileInNautilus(path.DirName(), path.value());
      break;
  }
}

}  // namespace internal

void ShowItemInFolder(Profile* profile, const base::FilePath& full_path) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  base::PostTaskWithTraitsAndReplyWithResult(
      FROM_HERE,
      {base::WithBaseSyncPrimitives(), base::MayBlock(),
       base::TaskPriority::USER_BLOCKING},
      base::BindOnce(&CheckNautilusIsDefault),
      base::BindOnce(&ShowItem, profile, full_path));
}

void OpenExternal(Profile* profile, const GURL& url) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  if (url.SchemeIs("mailto"))
    XDGEmail(url.spec());
  else
    XDGOpen(base::FilePath(), url.spec());
}

}  // namespace platform_util
