// 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.

// Implementation for the asynchronous interface to the Windows shell
// SHOpenWithDialog function.  The call is made on a dedicated UI thread in a
// single-threaded apartment.

#include "win8/test/open_with_dialog_async.h"

#include <shlobj.h>

#include "base/bind.h"
#include "base/callback.h"
#include "base/location.h"
#include "base/memory/ref_counted.h"
#include "base/single_thread_task_runner.h"
#include "base/thread_task_runner_handle.h"
#include "base/threading/platform_thread.h"
#include "base/threading/thread.h"
#include "base/win/windows_version.h"

namespace win8 {

namespace {

struct OpenWithContext {
  OpenWithContext(
      HWND parent_window_in,
      const base::string16& file_name_in,
      const base::string16& file_type_class_in,
      int open_as_info_flags_in,
      const scoped_refptr<base::SingleThreadTaskRunner>& client_runner_in,
      const OpenWithDialogCallback& callback_in);
  ~OpenWithContext();

  base::Thread thread;
  HWND parent_window;
  base::string16 file_name;
  base::string16 file_type_class;
  int open_as_info_flags;
  scoped_refptr<base::SingleThreadTaskRunner> client_runner;
  OpenWithDialogCallback callback;
};

OpenWithContext::OpenWithContext(
    HWND parent_window_in,
    const base::string16& file_name_in,
    const base::string16& file_type_class_in,
    int open_as_info_flags_in,
    const scoped_refptr<base::SingleThreadTaskRunner>& client_runner_in,
    const OpenWithDialogCallback& callback_in)
    : thread("OpenWithDialog"),
      parent_window(parent_window_in),
      file_name(file_name_in),
      file_type_class(file_type_class_in),
      open_as_info_flags(open_as_info_flags_in),
      client_runner(client_runner_in),
      callback(callback_in) {
  thread.init_com_with_mta(false);
  thread.Start();
}

OpenWithContext::~OpenWithContext() {}

// Runs the caller-provided |callback| with the result of the call to
// SHOpenWithDialog on the caller's initial thread.
void OnOpenWithDialogDone(OpenWithContext* context, HRESULT result) {
  DCHECK(context->client_runner->BelongsToCurrentThread());
  OpenWithDialogCallback callback(context->callback);

  // Join with the thread.
  delete context;

  // Run the client's callback.
  callback.Run(result);
}

// Calls SHOpenWithDialog (blocking), and returns the result back to the client
// thread.
void OpenWithDialogTask(OpenWithContext* context) {
  DCHECK_EQ(context->thread.GetThreadId(), base::PlatformThread::CurrentId());
  OPENASINFO open_as_info = {
    context->file_name.c_str(),
    context->file_type_class.c_str(),
    context->open_as_info_flags
  };

  HRESULT result = ::SHOpenWithDialog(context->parent_window, &open_as_info);

  // Bounce back to the calling thread to release resources and deliver the
  // callback.
  if (!context->client_runner->PostTask(
          FROM_HERE,
          base::Bind(&OnOpenWithDialogDone, context, result))) {
    // The calling thread has gone away. There's nothing to be done but leak.
    // In practice this is only likely to happen at shutdown, so there isn't
    // much of a concern that it'll happen in the real world.
    DLOG(ERROR) << "leaking OpenWith thread; result = " << std::hex << result;
  }
}

}  // namespace

void OpenWithDialogAsync(
    HWND parent_window,
    const base::string16& file_name,
    const base::string16& file_type_class,
    int open_as_info_flags,
    const OpenWithDialogCallback& callback) {
  DCHECK_GE(base::win::GetVersion(), base::win::VERSION_VISTA);
  OpenWithContext* context =
      new OpenWithContext(parent_window, file_name, file_type_class,
                          open_as_info_flags,
                          base::ThreadTaskRunnerHandle::Get(), callback);
  context->thread.message_loop()->PostTask(
      FROM_HERE,
      base::Bind(&OpenWithDialogTask, context));
}

}  // namespace win8
