// Copyright 2010-2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "renderer/win32/win32_renderer_client.h"

#include "base/logging.h"
#include "base/mutex.h"
#include "base/scoped_handle.h"
#include "base/system_util.h"
#include "base/util.h"
#include "renderer/renderer_client.h"
#include "renderer/renderer_command.pb.h"

namespace mozc {
namespace renderer {
namespace win32 {

namespace {
using ::mozc::commands::RendererCommand;

class SenderThread;
SenderThread *g_sender_thread = nullptr;

// Used to lock |g_sender_thread|.
Mutex *g_mutex = nullptr;

// Represents the module handle of this module.
volatile HMODULE g_module = nullptr;

// True if the the DLL received DLL_PROCESS_DETACH notification.
volatile bool g_module_unloaded = false;

// Represents the number of UI threads that are recognized by this module.
volatile LONG g_ui_thread_count = 0;

// Thread Local Storage (TLS) index to specify the current UI thread is
// initialized or not. if ::GetTlsValue(g_tls_index) returns non-zero
// value, the current thread is initialized.
volatile DWORD g_tls_index = TLS_OUT_OF_INDEXES;

class SenderThread {
 public:
  SenderThread(HANDLE command_event, HANDLE quit_event)
    : command_event_(command_event),
      quit_event_(quit_event) {
  }

  void RequestQuit() {
    ::SetEvent(quit_event_.get());
  }

  void UpdateCommand(const RendererCommand &new_command) {
    scoped_lock lock(&mutex_);
    renderer_command_.CopyFrom(new_command);
    ::SetEvent(command_event_.get());
  }

  void RenderLoop() {
    // Wait until desktop name is ready. b/10403163
    while (SystemUtil::GetDesktopNameAsString().empty()) {
      const DWORD wait_result = ::WaitForSingleObject(quit_event_.get(), 500);
      const DWORD wait_error = ::GetLastError();
      if (wait_result == WAIT_OBJECT_0) {
        return;
      }
      if (wait_result == WAIT_TIMEOUT) {
        continue;
      }
      LOG(ERROR) << "Unknown result: " << wait_result
                 << ", error: " << wait_error;
      return;
    }

    mozc::renderer::RendererClient renderer_client;
    while (true) {
      const HANDLE handles[] = {quit_event_.get(), command_event_.get()};
      const DWORD wait_result = ::WaitForMultipleObjects(
          arraysize(handles), handles, FALSE, INFINITE);
      const DWORD wait_error = ::GetLastError();
      if (g_module_unloaded) {
        break;
      }
      const DWORD kQuitEventSignaled = WAIT_OBJECT_0;
      const DWORD kRendererEventSignaled = WAIT_OBJECT_0 + 1;
      if (wait_result == kQuitEventSignaled) {
        // handles[0], that is, quit event is signaled.
        break;
      }
      if (wait_result != kRendererEventSignaled) {
        LOG(ERROR) << "WaitForMultipleObjects failed. error: " << wait_error;
        break;
      }
      // handles[1], that is, renderer event is signaled.
      RendererCommand command;
      {
        scoped_lock lock(&mutex_);
        command.Swap(&renderer_command_);
        ::ResetEvent(command_event_.get());
      }
      if (!renderer_client.ExecCommand(command)) {
        DLOG(ERROR) << "RendererClient::ExecCommand failed.";
      }
    }
  }

 private:
  ScopedHandle command_event_;
  ScopedHandle quit_event_;
  RendererCommand renderer_command_;
  Mutex mutex_;

  DISALLOW_COPY_AND_ASSIGN(SenderThread);
};

static DWORD WINAPI ThreadProc(void * /*unused*/) {
  SenderThread *thread = nullptr;
  {
    scoped_lock lock(g_mutex);
    thread = g_sender_thread;
  }
  if (thread != nullptr) {
    thread->RenderLoop();
    delete thread;
  }
  ::FreeLibraryAndExitThread(g_module, 0);
}

SenderThread *CreateSenderThread() {
  // Here we directly use CreateThread API rather than _beginthreadex because
  // the command sender thread will be eventually terminated via
  // FreeLibraryAndExitThread API. Regarding CRT memory resources, this will
  // be OK because this code will be running as DLL and the CRT can manage
  // thread specific resources through attach/detach notification in DllMain.
  DWORD thread_id = 0;
  ScopedHandle thread_handle(::CreateThread(
      nullptr, 0, ThreadProc, nullptr, CREATE_SUSPENDED, &thread_id));
  if (thread_handle.get() == nullptr) {
    // Failed to create the thread. Restore the reference count of the DLL.
    return nullptr;
  }

  // Increment the reference count of the IME DLL so that the DLL will not
  // be unloaded while the sender thread is running. The reference count
  // will be decremented by FreeLibraryAndExitThread API in the thread routine.
  HMODULE loaded_module = nullptr;
  if (::GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
                           reinterpret_cast<const wchar_t *>(g_module),
                           &loaded_module) == FALSE) {
    ::TerminateThread(thread_handle.get(), 0);
    return nullptr;
  }
  if (loaded_module != g_module) {
    ::TerminateThread(thread_handle.get(), 0);
    ::FreeLibrary(loaded_module);
    return nullptr;
  }

  // Create shared objects. We use manual reset events for simplicity.
  ScopedHandle command_event(::CreateEventW(nullptr, TRUE, FALSE, nullptr));
  ScopedHandle quit_event(::CreateEventW(nullptr, TRUE, FALSE, nullptr));
  if ((command_event.get() == nullptr) || (quit_event.get() == nullptr)) {
    ::TerminateThread(thread_handle.get(), 0);
    return nullptr;
  }

  scoped_ptr<SenderThread> thread(new SenderThread(
      command_event.take(), quit_event.take()));

  // Resume the thread.
  if (::ResumeThread(thread_handle.get()) == -1) {
    ::TerminateThread(thread_handle.get(), 0);
    ::FreeLibrary(loaded_module);
    return nullptr;
  }

  return thread.release();
}

bool CanIgnoreRequest(const RendererCommand &command) {
  if (g_module_unloaded) {
    return true;
  }
  if (g_tls_index == TLS_OUT_OF_INDEXES) {
    return true;
  }
  if ((::TlsGetValue(g_tls_index) == nullptr) &&
      !command.visible()) {
    // The sender threaed is not initialized and |command| is to hide the
    // renderer. We are likely to be able to skip this request.
    return true;
  }
  return false;
}

// Returns true when the required initialization is finished successfully.
bool EnsureUIThreadInitialized() {
  if (g_module_unloaded) {
    return false;
  }
  if (g_tls_index == TLS_OUT_OF_INDEXES) {
    return false;
  }
  if (::TlsGetValue(g_tls_index) != nullptr) {
    // already initialized.
    return true;
  }
  {
    scoped_lock lock(g_mutex);
    ++g_ui_thread_count;
    if (g_ui_thread_count == 1) {
      g_sender_thread = CreateSenderThread();
    }
  }
  // Mark this thread is initialized.
  ::TlsSetValue(g_tls_index, reinterpret_cast<void *>(1));
  return true;
}

}  // namespace

void Win32RendererClient::OnModuleLoaded(HMODULE module_handle) {
  g_module = module_handle;
  g_mutex = new Mutex();
  g_tls_index = ::TlsAlloc();
}

void Win32RendererClient::OnModuleUnloaded() {
  if (g_tls_index != TLS_OUT_OF_INDEXES) {
    ::TlsFree(g_tls_index);
  }
  delete g_mutex;
  g_module_unloaded = true;
  g_module = nullptr;
}

void Win32RendererClient::OnUIThreadUninitialized() {
  if (g_module_unloaded) {
    return;
  }
  if (g_tls_index == TLS_OUT_OF_INDEXES) {
    return;
  }
  if (::TlsGetValue(g_tls_index) == nullptr) {
    // Do nothing because this thread did not increment |g_ui_thread_count|.
    return;
  }
  {
    scoped_lock lock(g_mutex);
    if (g_ui_thread_count > 0) {
      --g_ui_thread_count;
      if (g_ui_thread_count == 0 && g_sender_thread != nullptr) {
        g_sender_thread->RequestQuit();
        g_sender_thread = nullptr;
      }
    }
  }
  // Mark this thread is uninitialized.
  ::TlsSetValue(g_tls_index, nullptr);
}

void Win32RendererClient::OnUpdated(const RendererCommand &command) {
  if (CanIgnoreRequest(command)) {
    return;
  }
  if (!EnsureUIThreadInitialized()) {
    return;
  }
  SenderThread *thread = nullptr;
  {
    scoped_lock lock(g_mutex);
    thread = g_sender_thread;
  }
  if (thread != nullptr) {
    thread->UpdateCommand(command);
  }
}

}  // namespace win32
}  // namespace renderer
}  // namespace mozc
