// 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/test/open_with_dialog_controller.h"

#include <shlobj.h>

#include "base/bind.h"
#include "base/callback.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/thread_task_runner_handle.h"
#include "base/threading/thread_checker.h"
#include "base/win/windows_version.h"
#include "win8/test/open_with_dialog_async.h"
#include "win8/test/ui_automation_client.h"

namespace win8 {

namespace {

const int kControllerTimeoutSeconds = 5;
const wchar_t kShellFlyoutClassName[] = L"Shell_Flyout";

// A callback invoked with the OpenWithDialogController's results. Said results
// are copied to |result_out| and |choices_out| and then |closure| is invoked.
// This function is in support of OpenWithDialogController::RunSynchronously.
void OnMakeDefaultComplete(
    const base::Closure& closure,
    HRESULT* result_out,
    std::vector<base::string16>* choices_out,
    HRESULT hr,
    std::vector<base::string16> choices) {
  *result_out = hr;
  *choices_out = choices;
  closure.Run();
}

}  // namespace

// Lives on the main thread and is owned by a controller. May outlive the
// controller (see Orphan).
class OpenWithDialogController::Context {
 public:
  Context();
  ~Context();

  base::WeakPtr<Context> AsWeakPtr();

  void Orphan();

  void Begin(HWND parent_window,
             const base::string16& url_protocol,
             const base::string16& program_name,
             const OpenWithDialogController::SetDefaultCallback& callback);

 private:
  enum State {
    // The Context has been constructed.
    CONTEXT_INITIALIZED,
    // The UI automation event handler is ready.
    CONTEXT_AUTOMATION_READY,
    // The automation results came back before the call to SHOpenWithDialog.
    CONTEXT_WAITING_FOR_DIALOG,
    // The call to SHOpenWithDialog returned before automation results.
    CONTEXT_WAITING_FOR_RESULTS,
    CONTEXT_FINISHED,
  };

  // Invokes the client's callback and destroys this instance.
  void NotifyClientAndDie();

  void OnTimeout();
  void OnInitialized(HRESULT result);
  void OnAutomationResult(HRESULT result, std::vector<base::string16> choices);
  void OnOpenWithComplete(HRESULT result);

  base::ThreadChecker thread_checker_;
  State state_;
  internal::UIAutomationClient automation_client_;
  HWND parent_window_;
  base::string16 file_name_;
  base::string16 file_type_class_;
  int open_as_info_flags_;
  OpenWithDialogController::SetDefaultCallback callback_;
  HRESULT open_with_result_;
  HRESULT automation_result_;
  std::vector<base::string16> automation_choices_;
  base::WeakPtrFactory<Context> weak_ptr_factory_;
  DISALLOW_COPY_AND_ASSIGN(Context);
};

OpenWithDialogController::Context::Context()
    : state_(CONTEXT_INITIALIZED),
      parent_window_(),
      open_as_info_flags_(),
      open_with_result_(E_FAIL),
      automation_result_(E_FAIL),
      weak_ptr_factory_(this) {}

OpenWithDialogController::Context::~Context() {
  DCHECK(thread_checker_.CalledOnValidThread());
}

base::WeakPtr<OpenWithDialogController::Context>
    OpenWithDialogController::Context::AsWeakPtr() {
  DCHECK(thread_checker_.CalledOnValidThread());
  return weak_ptr_factory_.GetWeakPtr();
}

void OpenWithDialogController::Context::Orphan() {
  DCHECK(thread_checker_.CalledOnValidThread());

  // The controller is being destroyed. Its client is no longer interested in
  // having the interaction continue.
  DLOG_IF(WARNING, (state_ == CONTEXT_AUTOMATION_READY ||
                    state_ == CONTEXT_WAITING_FOR_DIALOG))
      << "Abandoning the OpenWithDialog.";
  delete this;
}

void OpenWithDialogController::Context::Begin(
    HWND parent_window,
    const base::string16& url_protocol,
    const base::string16& program_name,
    const OpenWithDialogController::SetDefaultCallback& callback) {
  DCHECK(thread_checker_.CalledOnValidThread());

  parent_window_ = parent_window;
  file_name_ = url_protocol;
  file_type_class_.clear();
  open_as_info_flags_ = (OAIF_URL_PROTOCOL | OAIF_FORCE_REGISTRATION |
                         OAIF_REGISTER_EXT);
  callback_ = callback;

  // Post a delayed callback to abort the operation if it takes too long.
  base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
      FROM_HERE,
      base::Bind(&OpenWithDialogController::Context::OnTimeout, AsWeakPtr()),
      base::TimeDelta::FromSeconds(kControllerTimeoutSeconds));

  automation_client_.Begin(
      kShellFlyoutClassName,
      program_name,
      base::Bind(&OpenWithDialogController::Context::OnInitialized,
                 AsWeakPtr()),
      base::Bind(&OpenWithDialogController::Context::OnAutomationResult,
                 AsWeakPtr()));
}

void OpenWithDialogController::Context::NotifyClientAndDie() {
  DCHECK(thread_checker_.CalledOnValidThread());
  DCHECK_EQ(state_, CONTEXT_FINISHED);
  DLOG_IF(WARNING, SUCCEEDED(automation_result_) && FAILED(open_with_result_))
      << "Automation succeeded, yet SHOpenWithDialog failed.";

  // Ignore any future callbacks (such as the timeout) or calls to Orphan.
  weak_ptr_factory_.InvalidateWeakPtrs();
  callback_.Run(automation_result_, automation_choices_);
  delete this;
}

void OpenWithDialogController::Context::OnTimeout() {
  DCHECK(thread_checker_.CalledOnValidThread());
  // This is a LOG rather than a DLOG since it represents something that needs
  // to be investigated and fixed.
  LOG(ERROR) << __FUNCTION__ << " state: " << state_;

  state_ = CONTEXT_FINISHED;
  NotifyClientAndDie();
}

void OpenWithDialogController::Context::OnInitialized(HRESULT result) {
  DCHECK(thread_checker_.CalledOnValidThread());
  DCHECK_EQ(state_, CONTEXT_INITIALIZED);
  if (FAILED(result)) {
    automation_result_ = result;
    state_ = CONTEXT_FINISHED;
    NotifyClientAndDie();
    return;
  }
  state_ = CONTEXT_AUTOMATION_READY;
  OpenWithDialogAsync(
      parent_window_, file_name_, file_type_class_, open_as_info_flags_,
      base::Bind(&OpenWithDialogController::Context::OnOpenWithComplete,
                 weak_ptr_factory_.GetWeakPtr()));
}

void OpenWithDialogController::Context::OnAutomationResult(
    HRESULT result,
    std::vector<base::string16> choices) {
  DCHECK(thread_checker_.CalledOnValidThread());
  DCHECK_EQ(automation_result_, E_FAIL);

  automation_result_ = result;
  automation_choices_ = choices;
  switch (state_) {
    case CONTEXT_AUTOMATION_READY:
      // The results of automation are in and we're waiting for
      // SHOpenWithDialog to return.
      state_ = CONTEXT_WAITING_FOR_DIALOG;
      break;
    case CONTEXT_WAITING_FOR_RESULTS:
      state_ = CONTEXT_FINISHED;
      NotifyClientAndDie();
      break;
    default:
      NOTREACHED() << state_;
  }
}

void OpenWithDialogController::Context::OnOpenWithComplete(HRESULT result) {
  DCHECK(thread_checker_.CalledOnValidThread());
  DCHECK_EQ(open_with_result_, E_FAIL);

  open_with_result_ = result;
  switch (state_) {
    case CONTEXT_AUTOMATION_READY:
      // The interaction completed and we're waiting for the results from the
      // automation side to come in.
      state_ = CONTEXT_WAITING_FOR_RESULTS;
      break;
    case CONTEXT_WAITING_FOR_DIALOG:
      // All results are in.  Invoke the caller's callback.
      state_ = CONTEXT_FINISHED;
      NotifyClientAndDie();
      break;
    default:
      NOTREACHED() << state_;
  }
}

OpenWithDialogController::OpenWithDialogController() {}

OpenWithDialogController::~OpenWithDialogController() {
  // Orphan the context if this instance is being destroyed before the context
  // finishes its work.
  if (context_)
    context_->Orphan();
}

void OpenWithDialogController::Begin(
    HWND parent_window,
    const base::string16& url_protocol,
    const base::string16& program,
    const SetDefaultCallback& callback) {
  DCHECK_EQ(context_.get(), static_cast<Context*>(NULL));
  if (base::win::GetVersion() < base::win::VERSION_WIN8) {
    NOTREACHED() << "Windows 8 is required.";
    // The callback may not properly handle being run from Begin, so post a task
    // to this thread's task runner to call it.
    base::ThreadTaskRunnerHandle::Get()->PostTask(
        FROM_HERE,
        base::Bind(callback, E_FAIL, std::vector<base::string16>()));
    return;
  }

  context_ = (new Context())->AsWeakPtr();
  context_->Begin(parent_window, url_protocol, program, callback);
}

HRESULT OpenWithDialogController::RunSynchronously(
    HWND parent_window,
    const base::string16& protocol,
    const base::string16& program,
    std::vector<base::string16>* choices) {
  DCHECK_EQ(base::MessageLoop::current(),
            static_cast<base::MessageLoop*>(NULL));
  if (base::win::GetVersion() < base::win::VERSION_WIN8) {
    NOTREACHED() << "Windows 8 is required.";
    return E_FAIL;
  }

  HRESULT result = S_OK;
  base::MessageLoop message_loop;
  base::RunLoop run_loop;

  message_loop.PostTask(
      FROM_HERE,
      base::Bind(&OpenWithDialogController::Begin, base::Unretained(this),
                 parent_window, protocol, program,
                 Bind(&OnMakeDefaultComplete, run_loop.QuitClosure(),
                      &result, choices)));

  run_loop.Run();
  return result;
}

}  // namespace win8
