// 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 "base/basictypes.h"
#include "base/bind.h"
#include "base/callback.h"
#include "base/command_line.h"
#include "base/logging.h"
#include "base/memory/ref_counted.h"
#include "base/path_service.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/threading/sequenced_worker_pool.h"
#include "chrome/browser/extensions/api/messaging/native_messaging_host_manifest.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "content/public/browser/browser_thread.h"
#include "url/gurl.h"

namespace extensions {

namespace {

// Name of the command line switch used to pass handle of the native view to
// the native messaging host.
const char kParentWindowSwitchName[] = "parent-window";

base::FilePath GetHostManifestPathFromCommandLine(
    const std::string& native_host_name) {
  const std::string& value =
      CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
          switches::kNativeMessagingHosts);
  if (value.empty())
    return base::FilePath();

  std::vector<std::string> hosts;
  base::SplitString(value, ',', &hosts);
  for (size_t i = 0; i < hosts.size(); ++i) {
    std::vector<std::string> key_and_value;
    base::SplitString(hosts[i], '=', &key_and_value);
    if (key_and_value.size() != 2)
      continue;
    if (key_and_value[0] == native_host_name)
      return base::FilePath::FromUTF8Unsafe(key_and_value[1]);
  }

  return base::FilePath();
}


// Default implementation on NativeProcessLauncher interface.
class NativeProcessLauncherImpl : public NativeProcessLauncher {
 public:
  explicit NativeProcessLauncherImpl(gfx::NativeView native_view);
  virtual ~NativeProcessLauncherImpl();

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

 private:
  class Core : public base::RefCountedThreadSafe<Core> {
   public:
    explicit Core(gfx::NativeView native_view);
    void Launch(const GURL& origin,
                const std::string& native_host_name,
                LaunchedCallback callback);
    void Detach();

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

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

    bool detached_;

    // Handle of the native view corrsponding to the extension.
    gfx::NativeView native_view_;

    DISALLOW_COPY_AND_ASSIGN(Core);
  };

  scoped_refptr<Core> core_;

  DISALLOW_COPY_AND_ASSIGN(NativeProcessLauncherImpl);
};

NativeProcessLauncherImpl::Core::Core(gfx::NativeView native_view)
    : detached_(false),
      native_view_(native_view) {
}

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

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

void NativeProcessLauncherImpl::Core::Launch(
    const GURL& origin,
    const std::string& native_host_name,
    LaunchedCallback callback) {
  content::BrowserThread::PostBlockingPoolTask(
      FROM_HERE, base::Bind(&Core::DoLaunchOnThreadPool, this,
                            origin, native_host_name, callback));
}

void NativeProcessLauncherImpl::Core::DoLaunchOnThreadPool(
    const GURL& origin,
    const std::string& native_host_name,
    LaunchedCallback callback) {
  DCHECK(content::BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread());

  if (!NativeMessagingHostManifest::IsValidName(native_host_name)) {
    PostErrorResult(callback, RESULT_INVALID_NAME);
    return;
  }

  std::string error_message;
  scoped_ptr<NativeMessagingHostManifest> manifest;

  // First check if the manifest location is specified in the command line.
  base::FilePath manifest_path =
      GetHostManifestPathFromCommandLine(native_host_name);
  if (manifest_path.empty())
    manifest_path = FindManifest(native_host_name, &error_message);

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

  manifest = NativeMessagingHostManifest::Load(manifest_path, &error_message);

  if (!manifest) {
    LOG(ERROR) << "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(ERROR) << "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(ERROR) << "Native messaging host path must be absolute for "
               << native_host_name;
    PostErrorResult(callback, RESULT_NOT_FOUND);
    return;
#endif  // !defined(OS_WIN)
  }

  CommandLine command_line(host_path);
  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)
  int64 window_handle = reinterpret_cast<intptr_t>(native_view_);
  command_line.AppendSwitchASCII(kParentWindowSwitchName,
                                 base::Int64ToString(window_handle));
#endif  // !defined(OS_WIN)

  base::PlatformFile read_file;
  base::PlatformFile write_file;
  if (NativeProcessLauncher::LaunchNativeProcess(
          command_line, &read_file, &write_file)) {
    PostResult(callback, read_file, write_file);
  } else {
    PostErrorResult(callback, RESULT_FAILED_TO_START);
  }
}

void NativeProcessLauncherImpl::Core::CallCallbackOnIOThread(
    LaunchedCallback callback,
    LaunchResult result,
    base::PlatformFile read_file,
    base::PlatformFile write_file) {
  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
  if (detached_) {
    if (read_file != base::kInvalidPlatformFileValue)
      base::ClosePlatformFile(read_file);
    if (write_file != base::kInvalidPlatformFileValue)
      base::ClosePlatformFile(write_file);
    return;
  }

  callback.Run(result, read_file, write_file);
}

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

void NativeProcessLauncherImpl::Core::PostResult(
    const LaunchedCallback& callback,
    base::PlatformFile read_file,
    base::PlatformFile write_file) {
  content::BrowserThread::PostTask(
      content::BrowserThread::IO, FROM_HERE,
      base::Bind(&NativeProcessLauncherImpl::Core::CallCallbackOnIOThread,
                 this, callback, RESULT_SUCCESS, read_file, write_file));
}

NativeProcessLauncherImpl::NativeProcessLauncherImpl(
    gfx::NativeView native_view)
  : core_(new Core(native_view)) {
}

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

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

}  // namespace

// static
scoped_ptr<NativeProcessLauncher> NativeProcessLauncher::CreateDefault(
    gfx::NativeView native_view) {
  return scoped_ptr<NativeProcessLauncher>(
      new NativeProcessLauncherImpl(native_view));
}

}  // namespace extensions
