// 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.thread_id(), 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
