// 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/threading/thread_checker.h"
#include "base/threading/thread_task_runner_handle.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
