// Copyright (c) 2013 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 "win8/viewer/metro_viewer_process_host.h"

#include <shlobj.h>
#include <stdint.h>

#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/memory/ref_counted.h"
#include "base/path_service.h"
#include "base/process/process.h"
#include "base/strings/string16.h"
#include "base/synchronization/waitable_event.h"
#include "base/time/time.h"
#include "base/win/scoped_comptr.h"
#include "base/win/windows_version.h"
#include "ipc/ipc_channel_proxy.h"
#include "ipc/ipc_message.h"
#include "ipc/ipc_message_macros.h"
#include "ui/aura/remote_window_tree_host_win.h"
#include "ui/metro_viewer/metro_viewer_messages.h"
#include "win8/viewer/metro_viewer_constants.h"

namespace {

const int kViewerProcessConnectionTimeoutSecs = 60;

}  // namespace

namespace win8 {

// static
MetroViewerProcessHost* MetroViewerProcessHost::instance_ = NULL;

MetroViewerProcessHost::InternalMessageFilter::InternalMessageFilter(
    MetroViewerProcessHost* owner)
    : owner_(owner) {
}

void MetroViewerProcessHost::InternalMessageFilter::OnChannelConnected(
    int32_t peer_pid) {
  owner_->NotifyChannelConnected();
}

MetroViewerProcessHost::InternalMessageFilter::~InternalMessageFilter() {
}

MetroViewerProcessHost::MetroViewerProcessHost(
    const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner) {
  DCHECK(!instance_);
  instance_ = this;

  channel_ = IPC::ChannelProxy::Create(kMetroViewerIPCChannelName,
                                       IPC::Channel::MODE_NAMED_SERVER,
                                       this,
                                       ipc_task_runner);
}

MetroViewerProcessHost::~MetroViewerProcessHost() {
  if (!channel_) {
    instance_ = NULL;
    return;
  }

  base::ProcessId viewer_process_id = GetViewerProcessId();
  channel_->Close();
  if (message_filter_.get()) {
    // Wait for the viewer process to go away.
    if (viewer_process_id != base::kNullProcessId) {
      base::Process viewer_process =
          base::Process::OpenWithAccess(
              viewer_process_id,
              PROCESS_QUERY_INFORMATION | SYNCHRONIZE);
      if (viewer_process.IsValid()) {
        int exit_code;
        viewer_process.WaitForExit(&exit_code);
      }
    }
    channel_->RemoveFilter(message_filter_.get());
  }
  instance_ = NULL;
}

base::ProcessId MetroViewerProcessHost::GetViewerProcessId() {
  if (channel_)
    return channel_->GetPeerPID();
  return base::kNullProcessId;
}

bool MetroViewerProcessHost::LaunchViewerAndWaitForConnection(
    const base::string16& app_user_model_id) {
  DCHECK_EQ(base::kNullProcessId, channel_->GetPeerPID());

  channel_connected_event_.reset(new base::WaitableEvent(false, false));

  message_filter_ = new InternalMessageFilter(this);
  channel_->AddFilter(message_filter_.get());

  if (base::win::GetVersion() >= base::win::VERSION_WIN8) {
    base::win::ScopedComPtr<IApplicationActivationManager> activator;
    HRESULT hr = activator.CreateInstance(CLSID_ApplicationActivationManager);
    if (SUCCEEDED(hr)) {
      DWORD pid = 0;
      // Use the "connect" verb to
      hr = activator->ActivateApplication(
          app_user_model_id.c_str(), kMetroViewerConnectVerb, AO_NONE, &pid);
    }

    LOG_IF(ERROR, FAILED(hr)) << "Tried and failed to launch Metro Chrome. "
                              << "hr=" << std::hex << hr;
  } else {
    // For Windows 7 we need to launch the viewer ourselves.
    base::FilePath chrome_path;
    if (!PathService::Get(base::DIR_EXE, &chrome_path))
      return false;
    // TODO(cpu): launch with "-ServerName:DefaultBrowserServer"
    // note that the viewer might try to launch chrome again.
    CHECK(false);
  }

  // Having launched the viewer process, now we wait for it to connect.
  bool success =
      channel_connected_event_->TimedWait(base::TimeDelta::FromSeconds(
          kViewerProcessConnectionTimeoutSecs));
  channel_connected_event_.reset();
  return success;
}

bool MetroViewerProcessHost::Send(IPC::Message* msg) {
  return channel_->Send(msg);
}

bool MetroViewerProcessHost::OnMessageReceived(
    const IPC::Message& message) {
  DCHECK(CalledOnValidThread());
  bool handled = true;
  IPC_BEGIN_MESSAGE_MAP(MetroViewerProcessHost, message)
    IPC_MESSAGE_HANDLER(MetroViewerHostMsg_FileSaveAsDone,
                        OnFileSaveAsDone)
    IPC_MESSAGE_HANDLER(MetroViewerHostMsg_FileOpenDone,
                        OnFileOpenDone)
    IPC_MESSAGE_HANDLER(MetroViewerHostMsg_MultiFileOpenDone,
                        OnMultiFileOpenDone)
    IPC_MESSAGE_HANDLER(MetroViewerHostMsg_OpenURL, OnOpenURL)
    IPC_MESSAGE_HANDLER(MetroViewerHostMsg_SearchRequest, OnHandleSearchRequest)
    IPC_MESSAGE_HANDLER(MetroViewerHostMsg_SelectFolderDone,
                        OnSelectFolderDone)
    IPC_MESSAGE_HANDLER(MetroViewerHostMsg_SetTargetSurface, OnSetTargetSurface)
    IPC_MESSAGE_HANDLER(MetroViewerHostMsg_WindowSizeChanged,
                        OnWindowSizeChanged)
    IPC_MESSAGE_UNHANDLED(handled = false)
  IPC_END_MESSAGE_MAP()
  return handled ? true :
      aura::RemoteWindowTreeHostWin::Instance()->OnMessageReceived(message);
}

// static
void MetroViewerProcessHost::HandleActivateDesktop(
    const base::FilePath& path,
    bool ash_exit) {
  if (instance_) {
    instance_->Send(
        new MetroViewerHostMsg_ActivateDesktop(path, ash_exit));
  }
}

// static
void MetroViewerProcessHost::HandleMetroExit() {
  if (instance_)
    instance_->Send(new MetroViewerHostMsg_MetroExit());
}

// static
void MetroViewerProcessHost::HandleOpenFile(
    const base::string16& title,
    const base::FilePath& default_path,
    const base::string16& filter,
    const OpenFileCompletion& on_success,
    const FileSelectionCanceled& on_failure) {
  if (instance_) {
    instance_->HandleOpenFileImpl(title, default_path, filter, on_success,
                                  on_failure);
  }
}

// static
void MetroViewerProcessHost::HandleOpenMultipleFiles(
    const base::string16& title,
    const base::FilePath& default_path,
    const base::string16& filter,
    const OpenMultipleFilesCompletion& on_success,
    const FileSelectionCanceled& on_failure) {
  if (instance_) {
    instance_->HandleOpenMultipleFilesImpl(title, default_path, filter,
                                           on_success, on_failure);
  }
}

// static
void MetroViewerProcessHost::HandleSaveFile(
    const base::string16& title,
    const base::FilePath& default_path,
    const base::string16& filter,
    int filter_index,
    const base::string16& default_extension,
    const SaveFileCompletion& on_success,
    const FileSelectionCanceled& on_failure) {
  if (instance_) {
    instance_->HandleSaveFileImpl(title, default_path, filter, filter_index,
                                  default_extension, on_success, on_failure);
  }
}

// static
void MetroViewerProcessHost::HandleSelectFolder(
    const base::string16& title,
    const SelectFolderCompletion& on_success,
    const FileSelectionCanceled& on_failure) {
  if (instance_)
    instance_->HandleSelectFolderImpl(title, on_success, on_failure);
}

void MetroViewerProcessHost::HandleOpenFileImpl(
    const base::string16& title,
    const base::FilePath& default_path,
    const base::string16& filter,
    const OpenFileCompletion& on_success,
    const FileSelectionCanceled& on_failure) {
  // Can only have one of these operations in flight.
  DCHECK(file_open_completion_callback_.is_null());
  DCHECK(failure_callback_.is_null());

  file_open_completion_callback_ = on_success;
  failure_callback_ = on_failure;

  Send(new MetroViewerHostMsg_DisplayFileOpen(title, filter, default_path,
                                              false));
}

void MetroViewerProcessHost::HandleOpenMultipleFilesImpl(
    const base::string16& title,
    const base::FilePath& default_path,
    const base::string16& filter,
    const OpenMultipleFilesCompletion& on_success,
    const FileSelectionCanceled& on_failure) {
  // Can only have one of these operations in flight.
  DCHECK(multi_file_open_completion_callback_.is_null());
  DCHECK(failure_callback_.is_null());
  multi_file_open_completion_callback_ = on_success;
  failure_callback_ = on_failure;

  Send(new MetroViewerHostMsg_DisplayFileOpen(title, filter, default_path,
                                              true));
}

void MetroViewerProcessHost::HandleSaveFileImpl(
    const base::string16& title,
    const base::FilePath& default_path,
    const base::string16& filter,
    int filter_index,
    const base::string16& default_extension,
    const SaveFileCompletion& on_success,
    const FileSelectionCanceled& on_failure) {
  MetroViewerHostMsg_SaveAsDialogParams params;
  params.title = title;
  params.default_extension = default_extension;
  params.filter = filter;
  params.filter_index = filter_index;
  params.suggested_name = default_path;

  // Can only have one of these operations in flight.
  DCHECK(file_saveas_completion_callback_.is_null());
  DCHECK(failure_callback_.is_null());
  file_saveas_completion_callback_ = on_success;
  failure_callback_ = on_failure;

  Send(new MetroViewerHostMsg_DisplayFileSaveAs(params));
}

void MetroViewerProcessHost::HandleSelectFolderImpl(
    const base::string16& title,
    const SelectFolderCompletion& on_success,
    const FileSelectionCanceled& on_failure) {
  // Can only have one of these operations in flight.
  DCHECK(select_folder_completion_callback_.is_null());
  DCHECK(failure_callback_.is_null());
  select_folder_completion_callback_ = on_success;
  failure_callback_ = on_failure;

  Send(new MetroViewerHostMsg_DisplaySelectFolder(title));
}

void MetroViewerProcessHost::NotifyChannelConnected() {
  if (channel_connected_event_)
    channel_connected_event_->Signal();
}

void MetroViewerProcessHost::OnFileSaveAsDone(bool success,
                                              const base::FilePath& filename,
                                              int filter_index) {
  if (success)
    file_saveas_completion_callback_.Run(filename, filter_index, NULL);
  else
    failure_callback_.Run(NULL);
  file_saveas_completion_callback_.Reset();
  failure_callback_.Reset();
}


void MetroViewerProcessHost::OnFileOpenDone(bool success,
                                            const base::FilePath& filename) {
  if (success)
    file_open_completion_callback_.Run(base::FilePath(filename), 0, NULL);
  else
    failure_callback_.Run(NULL);
  file_open_completion_callback_.Reset();
  failure_callback_.Reset();
}

void MetroViewerProcessHost::OnMultiFileOpenDone(
    bool success,
    const std::vector<base::FilePath>& files) {
  if (success)
    multi_file_open_completion_callback_.Run(files, NULL);
  else
    failure_callback_.Run(NULL);
  multi_file_open_completion_callback_.Reset();
  failure_callback_.Reset();
}

void MetroViewerProcessHost::OnSelectFolderDone(
    bool success,
    const base::FilePath& folder) {
  if (success)
    select_folder_completion_callback_.Run(base::FilePath(folder), 0, NULL);
  else
    failure_callback_.Run(NULL);
  select_folder_completion_callback_.Reset();
  failure_callback_.Reset();
}

}  // namespace win8
