// 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/extensions/api/messaging/native_process_launcher.h"

#include <inttypes.h>
#include <utility>

#include "base/bind.h"
#include "base/callback.h"
#include "base/command_line.h"
#include "base/files/file_util.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/strings/stringprintf.h"
#include "base/task_scheduler/post_task.h"
#include "build/build_config.h"
#include "chrome/browser/extensions/api/messaging/native_messaging_host_manifest.h"
#include "chrome/common/chrome_paths.h"
#include "content/public/browser/browser_thread.h"
#include "url/gurl.h"

#if defined(OS_WIN)
#include "ui/views/win/hwnd_util.h"
#endif

namespace extensions {

namespace {

// Default implementation on NativeProcessLauncher interface.
class NativeProcessLauncherImpl : public NativeProcessLauncher {
 public:
  NativeProcessLauncherImpl(bool allow_user_level_hosts,
                            intptr_t native_window);
  ~NativeProcessLauncherImpl() override;

  void Launch(const GURL& origin,
              const std::string& native_host_name,
              const LaunchedCallback& callback) const override;

 private:
  class Core : public base::RefCountedThreadSafe<Core> {
   public:
    Core(bool allow_user_level_hosts, intptr_t native_window);
    void Launch(const GURL& origin,
                const std::string& native_host_name,
                const LaunchedCallback& callback);
    void Detach();

   private:
    friend class base::RefCountedThreadSafe<Core>;
    virtual ~Core();

    void DoLaunchOnThreadPool(const GURL& origin,
                              const std::string& native_host_name,
                              const LaunchedCallback& callback);
    void PostErrorResult(const LaunchedCallback& callback, LaunchResult error);
    void PostResult(const LaunchedCallback& callback,
                    base::Process process,
                    base::File read_file,
                    base::File write_file);
    void CallCallbackOnIOThread(const LaunchedCallback& callback,
                                LaunchResult result,
                                base::Process process,
                                base::File read_file,
                                base::File write_file);

    bool detached_;

    bool allow_user_level_hosts_;

#if defined(OS_WIN)
    // Handle of the native window corresponding to the extension.
    intptr_t window_handle_;
#endif // OS_WIN

    DISALLOW_COPY_AND_ASSIGN(Core);
  };

  scoped_refptr<Core> core_;

  DISALLOW_COPY_AND_ASSIGN(NativeProcessLauncherImpl);
};

NativeProcessLauncherImpl::Core::Core(bool allow_user_level_hosts,
                                      intptr_t window_handle)
    : detached_(false),
      allow_user_level_hosts_(allow_user_level_hosts)
#if defined(OS_WIN)
      , window_handle_(window_handle)
#endif // OS_WIN
{}

NativeProcessLauncherImpl::Core::~Core() {
  DCHECK(detached_);
}

void NativeProcessLauncherImpl::Core::Detach() {
  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
  detached_ = true;
}

void NativeProcessLauncherImpl::Core::Launch(
    const GURL& origin,
    const std::string& native_host_name,
    const LaunchedCallback& callback) {
  base::PostTaskWithTraits(FROM_HERE,
                           {base::MayBlock(), base::TaskPriority::USER_VISIBLE},
                           base::BindOnce(&Core::DoLaunchOnThreadPool, this,
                                          origin, native_host_name, callback));
}

void NativeProcessLauncherImpl::Core::DoLaunchOnThreadPool(
    const GURL& origin,
    const std::string& native_host_name,
    const LaunchedCallback& callback) {
  if (!NativeMessagingHostManifest::IsValidName(native_host_name)) {
    PostErrorResult(callback, RESULT_INVALID_NAME);
    return;
  }

  std::string error_message;
  base::FilePath manifest_path =
      FindManifest(native_host_name, allow_user_level_hosts_, &error_message);

  if (manifest_path.empty()) {
    LOG(WARNING) << "Can't find manifest for native messaging host "
                 << native_host_name;
    PostErrorResult(callback, RESULT_NOT_FOUND);
    return;
  }

  std::unique_ptr<NativeMessagingHostManifest> manifest =
      NativeMessagingHostManifest::Load(manifest_path, &error_message);

  if (!manifest) {
    LOG(WARNING) << "Failed to load manifest for native messaging host "
                 << native_host_name << ": " << error_message;
    PostErrorResult(callback, RESULT_NOT_FOUND);
    return;
  }

  if (manifest->name() != native_host_name) {
    LOG(WARNING) << "Failed to load manifest for native messaging host "
                 << native_host_name
                 << ": Invalid name specified in the manifest.";
    PostErrorResult(callback, RESULT_NOT_FOUND);
    return;
  }

  if (!manifest->allowed_origins().MatchesSecurityOrigin(origin)) {
    // Not an allowed origin.
    PostErrorResult(callback, RESULT_FORBIDDEN);
    return;
  }

  base::FilePath host_path = manifest->path();
  if (!host_path.IsAbsolute()) {
    // On Windows host path is allowed to be relative to the location of the
    // manifest file. On all other platforms the path must be absolute.
#if defined(OS_WIN)
    host_path = manifest_path.DirName().Append(host_path);
#else  // defined(OS_WIN)
    LOG(WARNING) << "Native messaging host path must be absolute for "
                 << native_host_name;
    PostErrorResult(callback, RESULT_NOT_FOUND);
    return;
#endif  // !defined(OS_WIN)
  }

  // In case when the manifest file is there, but the host binary doesn't exist
  // report the NOT_FOUND error.
  if (!base::PathExists(host_path)) {
    LOG(WARNING)
        << "Found manifest, but not the binary for native messaging host "
        << native_host_name << ". Host path specified in the manifest: "
        << host_path.AsUTF8Unsafe();
    PostErrorResult(callback, RESULT_NOT_FOUND);
    return;
  }

  base::CommandLine command_line(host_path);
  // Note: The origin must be the first argument, so do not use AppendSwitch*
  // hereafter because CommandLine inserts these switches before the other
  // arguments.
  command_line.AppendArg(origin.spec());

  // Pass handle of the native view window to the native messaging host. This
  // way the host will be able to create properly focused UI windows.
#if defined(OS_WIN)
  command_line.AppendArg(
      base::StringPrintf("--parent-window=%" PRIdPTR, window_handle_));
#endif  // !defined(OS_WIN)

  base::Process process;
  base::File read_file;
  base::File write_file;
  if (NativeProcessLauncher::LaunchNativeProcess(
          command_line, &process, &read_file, &write_file)) {
    PostResult(callback, std::move(process), std::move(read_file),
               std::move(write_file));
  } else {
    PostErrorResult(callback, RESULT_FAILED_TO_START);
  }
}

void NativeProcessLauncherImpl::Core::CallCallbackOnIOThread(
    const LaunchedCallback& callback,
    LaunchResult result,
    base::Process process,
    base::File read_file,
    base::File write_file) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
  if (detached_)
    return;

  callback.Run(result, std::move(process), std::move(read_file),
               std::move(write_file));
}

void NativeProcessLauncherImpl::Core::PostErrorResult(
    const LaunchedCallback& callback,
    LaunchResult error) {
  content::BrowserThread::PostTask(
      content::BrowserThread::IO, FROM_HERE,
      base::BindOnce(&NativeProcessLauncherImpl::Core::CallCallbackOnIOThread,
                     this, callback, error, Passed(base::Process()),
                     Passed(base::File()), Passed(base::File())));
}

void NativeProcessLauncherImpl::Core::PostResult(
    const LaunchedCallback& callback,
    base::Process process,
    base::File read_file,
    base::File write_file) {
  content::BrowserThread::PostTask(
      content::BrowserThread::IO, FROM_HERE,
      base::BindOnce(&NativeProcessLauncherImpl::Core::CallCallbackOnIOThread,
                     this, callback, RESULT_SUCCESS, Passed(&process),
                     Passed(&read_file), Passed(&write_file)));
}

NativeProcessLauncherImpl::NativeProcessLauncherImpl(
    bool allow_user_level_hosts,
    intptr_t window_handle)
    : core_(new Core(allow_user_level_hosts, window_handle)) {
}

NativeProcessLauncherImpl::~NativeProcessLauncherImpl() {
  core_->Detach();
}

void NativeProcessLauncherImpl::Launch(const GURL& origin,
                                       const std::string& native_host_name,
                                       const LaunchedCallback& callback) const {
  core_->Launch(origin, native_host_name, callback);
}

}  // namespace

// static
std::unique_ptr<NativeProcessLauncher> NativeProcessLauncher::CreateDefault(
    bool allow_user_level_hosts,
    gfx::NativeView native_view) {
  intptr_t window_handle = 0;
#if defined(OS_WIN)
  window_handle = reinterpret_cast<intptr_t>(
      views::HWNDForNativeView(native_view));
#endif
  return std::unique_ptr<NativeProcessLauncher>(
      new NativeProcessLauncherImpl(allow_user_level_hosts, window_handle));
}

}  // namespace extensions
