// 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 "win32/ime/ime_ui_window.h"

#define _ATL_NO_AUTOMATIC_NAMESPACE
#define _WTL_NO_AUTOMATIC_NAMESPACE
#define _ATL_NO_HOSTING
#include <atlbase.h>
#include <atlapp.h>
#include <atlstr.h>
#include <atlwin.h>
#include <atlmisc.h>
#include <strsafe.h>

#include <memory>

#include "base/const.h"
#include "base/logging.h"
#include "base/process.h"
#include "base/process_mutex.h"
#include "base/run_level.h"
#include "base/scoped_handle.h"
#include "base/singleton.h"
#include "base/win_util.h"
#include "client/client_interface.h"
#include "config/config_handler.h"
#include "renderer/renderer_command.pb.h"
#include "renderer/win32/win32_renderer_client.h"
#include "session/output_util.h"
#include "win32/base/conversion_mode_util.h"
#include "win32/base/indicator_visibility_tracker.h"
#include "win32/base/imm_util.h"
#include "win32/base/string_util.h"
#include "win32/base/win32_window_util.h"
#include "win32/ime/ime_core.h"
#include "win32/ime/ime_impl_imm.h"
#include "win32/ime/ime_language_bar.h"
#include "win32/ime/ime_scoped_context.h"
#include "win32/ime/ime_types.h"
#include "win32/ime/ime_ui_context.h"
#include "win32/ime/ime_ui_visibility_tracker.h"

namespace mozc {
namespace win32 {
namespace {

using ATL::CRegKey;
using ATL::CStringA;
using ATL::CWindow;
using WTL::CPoint;
using WTL::CRect;

using ::mozc::renderer::win32::Win32RendererClient;
using ::std::unique_ptr;

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

// As filed in b/3088049 or b/4271156, the IME module (e.g. GIMEJa.ime) is
// sometimes unloaded too early. You can use this macro to guard callback
// functions from being called in such situation.
#define DANGLING_CALLBACK_GUARD(return_code)   \
  do {                                         \
    if (g_module_unloaded) {                   \
      return (return_code);                    \
    }                                          \
  } while (false)

// A global variable of mozc::once_t, which is POD, has no bad side effect.
static once_t g_launch_set_default_dialog = MOZC_ONCE_INIT;

void LaunchSetDefaultDialog() {
  const config::Config &config = config::ConfigHandler::GetConfig();
  if (config.has_check_default() && !config.check_default()) {
    // User opted out the default IME checking. Do nothing.
    return;
  }

  if (ImeUtil::IsDefault()) {
    // Mozc has already been the default IME. Do nothing.
    return;
  }

  {
    mozc::ProcessMutex mutex("set_default_dialog");
    if (!mutex.Lock()) {
      VLOG(1) << "SetDefaultDialog is already launched";
      return;
    }
    // mutex is unlocked here
  }

  VLOG(1) << "Launching SetDefaultDialog";
  // Even if SetDefaultDialog is launched multiple times,
  // it's safe because mozc_tool also checks the existence of
  // the process with ProcessMutex.
  mozc::Process::SpawnMozcProcess(mozc::kMozcTool,
                                  "--mode=set_default_dialog");
}

bool IsProcessSandboxedImpl() {
  bool is_restricted = false;
  if (!WinUtil::IsProcessRestricted(::GetCurrentProcess(), &is_restricted)) {
    return true;
  }
  if (is_restricted) {
    return true;
  }

  bool in_appcontainer = false;
  if (!WinUtil::IsProcessInAppContainer(::GetCurrentProcess(),
                                        &in_appcontainer)) {
    return true;
  }

  return in_appcontainer;
}

bool IsProcessSandboxed() {
  // Thread safety is not required.
  static bool sandboxed = IsProcessSandboxedImpl();
  return sandboxed;
}

// This class is expected to be used a singleton object to enable Win32
// message-based event callback from the renderer to the client mainly
// to support mouse operation on the candidate list.
class PrivateRendererMessageInitializer {
 public:
  PrivateRendererMessageInitializer()
      : private_renderer_message_(
            ::RegisterWindowMessage(mozc::kMessageReceiverMessageName)) {}

  // Adds an exceptional rule for the message filter which prevents from
  // receiving a window message from a process in lower integrity level.
  // Returns true if the operation completed successfully.  Make sure to
  // call this method once per window, otherwise this function returns false.
  bool Initialize(HWND target_window) {
    if (private_renderer_message_ == 0) {
      return false;
    }
    if (!::IsWindow(target_window)) {
      return false;
    }
    return WindowUtil::ChangeMessageFilter(
        target_window, private_renderer_message_);
  }

  // Returns true if the specified message ID is the callback message.
  bool IsPrivateRendererMessage(UINT message) const {
    if (private_renderer_message_ == 0) {
      return false;
    }
    return (private_renderer_message_ == message);
  }

 private:
  UINT private_renderer_message_;
  DISALLOW_COPY_AND_ASSIGN(PrivateRendererMessageInitializer);
};

void UpdateCommand(const UIContext &context,
                   HWND ui_window,
                   const UIVisibilityTracker &ui_visibility_tracker,
                   mozc::commands::RendererCommand *command) {
  typedef ::mozc::commands::RendererCommand::ApplicationInfo ApplicationInfo;
  typedef ::mozc::commands::RendererCommand_IndicatorInfo IndicatorInfo;
  typedef ::mozc::commands::CompositionMode CompositionMode;

  const bool show_composition_window =
      ui_visibility_tracker.IsCompositionWindowVisible();
  const bool show_candidate_window =
      ui_visibility_tracker.IsCandidateWindowVisible();
  const bool show_suggest_window =
      ui_visibility_tracker.IsSuggestWindowVisible();

  vector<wstring> candidate_list;
  DWORD focused_index = 0;
  if (!context.IsEmpty() && context.GetOpenStatus()) {
    // Copy the last output.
    context.GetLastOutput(command->mutable_output());

    bool composition_window_visible = false;
    bool candidate_window_visible = false;
    bool suggest_window_visible = false;

    // Check if composition window is actually visible.
    if (command->output().has_preedit()) {
      composition_window_visible = show_composition_window;
    }

    // Check if suggest window and candidate window are actually visible.
    if (command->output().has_candidates() &&
        command->output().candidates().has_category()) {
      switch (command->output().candidates().category()) {
        case commands::SUGGESTION:
          suggest_window_visible = show_suggest_window;
          break;
        case commands::CONVERSION:
        case commands::PREDICTION:
          candidate_window_visible = show_candidate_window;
          break;
        default:
          // do nothing.
          break;
      }
    }

    if (composition_window_visible || candidate_window_visible ||
        suggest_window_visible) {
      command->set_visible(true);
    }
  }

  const CWindow target_window(context.GetAttachedWindow());
  ApplicationInfo &app_info = *command->mutable_application_info();
  app_info.set_process_id(::GetCurrentProcessId());
  app_info.set_thread_id(::GetCurrentThreadId());
  app_info.set_target_window_handle(
      reinterpret_cast<uint32>(target_window.m_hWnd));
  app_info.set_receiver_handle(reinterpret_cast<uint32>(ui_window));
  app_info.set_input_framework(ApplicationInfo::IMM32);
  int visibility = ApplicationInfo::ShowUIDefault;
  if (show_composition_window) {
    // Note that |ApplicationInfo::ShowCompositionWindow| represents that the
    // application does not mind the IME showing its own composition window.
    // This bit does not mean that |command| requires the composition window.
    visibility |= ApplicationInfo::ShowCompositionWindow;
  }
  if (show_candidate_window) {
    // Note that |ApplicationInfo::ShowCandidateWindow| represents that the
    // application does not mind the IME showing its own candidate window.
    // This bit does not mean that |command| requires the suggest window.
    visibility |= ApplicationInfo::ShowCandidateWindow;
  }
  if (show_suggest_window) {
    // Note that |ApplicationInfo::ShowCandidateWindow| represents that the
    // application does not mind the IME showing its own candidate window.
    // This bit does not mean that |command| requires the suggest window.
    visibility |= ApplicationInfo::ShowSuggestWindow;
  }
  app_info.set_ui_visibilities(visibility);

  // Honor visibility bits for UI-less mode.
  if (visibility != 0 && context.IsModeIndicatorEnabled()) {
    IndicatorVisibilityTracker *indicator_tracker =
        context.indicator_visibility_tracker();
    if (indicator_tracker != nullptr) {
      if (indicator_tracker->IsVisible()) {
        DWORD native_mode = 0;
        CompositionMode mode = commands::DIRECT;
        if (context.GetConversionMode(&native_mode) &&
            ConversionModeUtil::ToMozcMode(
                native_mode,
                &mode)) {
          if (!command->has_output()) {
            context.GetLastOutput(command->mutable_output());
          }
          command->set_visible(true);
          IndicatorInfo *info = app_info.mutable_indicator_info();
          info->mutable_status()->set_activated(context.GetOpenStatus());
          info->mutable_status()->set_mode(mode);
        }
      }
    }
  }

  context.FillFontInfo(&app_info);
  context.FillCaretInfo(&app_info);
  context.FillCompositionForm(&app_info);
  context.FillCandidateForm(&app_info);
  // UIContext::FillCharPosition is subject to cause b/3208669, b/3096191,
  // b/3212271, b/3223011, and b/4285222.
  // So we do not retrieve IMM32 related positional information when the
  // renderer hides all the UI windows.
  if (command->visible()) {
    context.FillCharPosition(&app_info);
  }
}

// Returns a HIMC assuming from the handle of a UI window.
// Returns nullptr if it is not available.
HIMC GetSafeHIMC(HWND window_handle) {
  if (!::IsWindow(window_handle)) {
    return nullptr;
  }

  const HIMC himc =
      reinterpret_cast<HIMC>(::GetWindowLongPtr(window_handle, IMMGWLP_IMC));

  // As revealed in b/3207711, ImeSetActiveContext is called without any
  // prior call to ImeSelect.  Perhaps this horrible situation might come from
  // CUAS's implementation in XP.
  // We will not use a HIMC as long as it seems to be uninitialized.
  if (!ImeCore::IsInputContextInitialized(himc)) {
    return nullptr;
  }

  return himc;
}

bool TurnOnIMEAndTryToReconvertFromIME(HWND hwnd) {
  const HIMC himc = GetSafeHIMC(hwnd);
  if (himc == nullptr) {
    return false;
  }
  if (!mozc::win32::ImeCore::TurnOnIMEAndTryToReconvertFromIME(himc)) {
    return false;
  }
  return true;
}

class LangBarCallbackImpl : public LangBarCallback {
 public:
  explicit LangBarCallbackImpl(HWND hwnd)
      : hwnd_(hwnd),
        reference_count_(1) {
  }

  virtual ~LangBarCallbackImpl() {
  }

  virtual ULONG AddRef() {
    const LONG count = ::InterlockedIncrement(&reference_count_);
    return max(count, 0);
  }

  virtual ULONG Release() {
    const LONG count = ::InterlockedDecrement(&reference_count_);
    if (count <= 0) {
      delete this;
      return 0;
    }
    return count;
  }

  // This method is called back by the lang bar when an item on the langbar is
  // selected.
  virtual HRESULT OnMenuSelect(MenuId menu_id) {
    DANGLING_CALLBACK_GUARD(E_FAIL);
    if (::IsWindow(hwnd_) == FALSE) {
      return E_FAIL;
    }
    // TODO(yukawa): Check run level.
    HRESULT result = S_OK;
    switch (menu_id) {
      case LangBarCallback::kDirect: {
        result = SetInputMode(mozc::commands::DIRECT);
        break;
      }
      case LangBarCallback::kHiragana: {
        result = SetInputMode(mozc::commands::HIRAGANA);
        break;
      }
      case LangBarCallback::kFullKatakana: {
        result = SetInputMode(mozc::commands::FULL_KATAKANA);
        break;
      }
      case LangBarCallback::kHalfAlphanumeric: {
        result = SetInputMode(mozc::commands::HALF_ASCII);
        break;
      }
      case LangBarCallback::kFullAlphanumeric: {
        result = SetInputMode(mozc::commands::FULL_ASCII);
        break;
      }
      case LangBarCallback::kHalfKatakana: {
        result = SetInputMode(mozc::commands::HALF_KATAKANA);
        break;
      }
      case LangBarCallback::kProperty: {
        // Open the config dialog.
        if (!mozc::Process::SpawnMozcProcess(
                mozc::kMozcTool, "--mode=config_dialog")) {
          result = E_FAIL;
        }
        break;
      }
      case LangBarCallback::kDictionary: {
        // Open the dictionary tool.
        if (!mozc::Process::SpawnMozcProcess(
                mozc::kMozcTool, "--mode=dictionary_tool")) {
          result = E_FAIL;
        }
        break;
      }
      case LangBarCallback::kWordRegister: {
        // Open the word register dialog.
        if (!mozc::Process::SpawnMozcProcess(
                mozc::kMozcTool, "--mode=word_register_dialog")) {
          result = E_FAIL;
        }
        break;
      }
      case LangBarCallback::kHandWriting: {
        // Open the Hand Writing Tool.
        if (!mozc::Process::SpawnMozcProcess(
                mozc::kMozcTool, "--mode=hand_writing")) {
          result = E_FAIL;
        }
        break;
      }
      case LangBarCallback::kCharacterPalette: {
        // Open the Character Palette dialog.
        if (!mozc::Process::SpawnMozcProcess(
                mozc::kMozcTool, "--mode=character_palette")) {
          result = E_FAIL;
        }
        break;
      }
      case LangBarCallback::kReconversion: {
        if (!TurnOnIMEAndTryToReconvertFromIME(hwnd_)) {
          result = E_FAIL;
        }
        break;
      }
      case LangBarCallback::kAbout: {
        // Open the about dialog.
        if (!mozc::Process::SpawnMozcProcess(mozc::kMozcTool,
                                             "--mode=about_dialog")) {
          result = E_FAIL;
        }
        break;
      }
      case LangBarCallback::kHelp: {
        // Open the about dialog.
        const char kHelpUrl[] = "http://www.google.com/support/ime/japanese";
        if (!mozc::Process::OpenBrowser(kHelpUrl)) {
          result = E_FAIL;
        }
        break;
      }
      default: {
        break;
      }
    }
    return result;
  }

 private:
  HRESULT SetInputMode(mozc::commands::CompositionMode mode) {
    const HIMC himc = GetSafeHIMC(hwnd_);
    if (himc == nullptr) {
      return E_FAIL;
    }
    if (mode == mozc::commands::DIRECT) {
      // Close IME.
      if (::ImmSetOpenStatus(himc, FALSE) == FALSE) {
        return E_FAIL;
      }
      return S_OK;
    }

    const bool is_open = (::ImmGetOpenStatus(himc) != FALSE);
    if (!is_open) {
      if (::ImmSetOpenStatus(himc, TRUE) == FALSE) {
        return E_FAIL;
      }
    }

    const UIContext context(himc);
    uint32 imm32_composition_mode = 0;
    if (!win32::ConversionModeUtil::ToNativeMode(
            mode, context.IsKanaInputPreferred(),
            &imm32_composition_mode)) {
      return E_FAIL;
    }

    DWORD composition_mode = 0;
    DWORD sentence_mode = 0;
    if (::ImmGetConversionStatus(himc, &composition_mode, &sentence_mode) ==
        FALSE) {
      return E_FAIL;
    }
    composition_mode = static_cast<DWORD>(imm32_composition_mode);
    DWORD visible_composition_mode = 0;
    DWORD logical_composition_mode = 0;
    if (context.GetVisibleConversionMode(&visible_composition_mode) &&
        context.GetLogicalConversionMode(&logical_composition_mode) &&
        (composition_mode != visible_composition_mode) &&
        (composition_mode == logical_composition_mode)) {
      // The visible conversion mode is different from the selected mode but the
      // actual conversion mode is the same to the selected mode. In this case,
      // ImmSetConversionStatus cannot be suitable because the actual conversion
      // mode will not be changed. So we will send SwitchInputMode command
      // explicitly.
      mozc::win32::ImeCore::SwitchInputMode(himc, composition_mode, true);
    } else if (::ImmSetConversionStatus(
                   himc, composition_mode, sentence_mode) == FALSE) {
      return E_FAIL;
    }
    return S_OK;
  }

  // Represents the reference count to an instance.
  // volatile modifier is added to conform with InterlockedIncrement API.
  volatile LONG reference_count_;
  HWND hwnd_;

  DISALLOW_COPY_AND_ASSIGN(LangBarCallbackImpl);
};

// TODO(yukawa): Refactor for unit tests and better integration with ImeCore.
class DefaultUIWindow {
 public:
  explicit DefaultUIWindow(HWND hwnd)
      : hwnd_(hwnd),
        langbar_callback_(new LangBarCallbackImpl(hwnd)),
        language_bar_(new LanguageBar),
        has_pending_langbar_update_(false) {
  }

  ~DefaultUIWindow() {
    langbar_callback_->Release();
    langbar_callback_ = nullptr;
  }

  void UninitLangBar() {
    CancelDeferredLangBarUpdateIfExists();
    language_bar_->UninitLanguageBar();
  }

  void OnStartComposition(const UIContext &context) {
    context.ui_visibility_tracker()->OnStartComposition();
  }

  void OnComposition(
      const UIContext &context, wchar_t latest_change,
      const CompositionChangeAttributes &attributes) {
    context.ui_visibility_tracker()->OnComposition();
  }

  void OnEndComposition(const UIContext &context) {
    context.ui_visibility_tracker()->OnEndComposition();
  }

  LRESULT OnNotify(const UIContext &context,
                   DWORD sub_message, LPARAM lParam) {
    context.ui_visibility_tracker()->OnNotify(sub_message, lParam);

    LRESULT result = 0;
    switch (sub_message) {
      case IMN_CLOSESTATUSWINDOW:
        break;
      case IMN_OPENSTATUSWINDOW:
        break;
      case IMN_SETCONVERSIONMODE:
        UpdateIndicator(context);
        result = (UpdateLangBar(context, kDeferred) ? 0 : 1);
        break;
      case IMN_SETSENTENCEMODE:
        // Do nothing because we only support IME_SMODE_PHRASEPREDICT, which
        // is not shown in our LangBar.
        // See b/2913510, b/2954777, and b/2955175 for details.
        break;
      case IMN_SETOPENSTATUS:
        UpdateIndicator(context);
        result = (UpdateLangBar(context, kDeferred) ? 0 : 1);
        break;
      case IMN_SETCANDIDATEPOS: {
        if (lParam & 0x1) {
          UpdateCandidate(context, kMoveFocusedWindow);
        }
        break;
      }
      case IMN_SETCOMPOSITIONFONT:
        if (!context.IsEmpty() && context.GetOpenStatus()) {
          LOGFONT font;
          if (context.GetCompositionFont(&font)) {
            // TODO(yukawa):
            // - Update the composition window.
          }
        }
        break;
      case IMN_SETCOMPOSITIONWINDOW:
        // TODO(yukawa): Use message hook instead.
        UpdateCandidate(context, kMoveFocusedWindow);
        break;
      case IMN_SETSTATUSWINDOWPOS:
        // TODO(yukawa):
        // - Redraw status window.
        break;
      case IMN_GUIDELINE:
        break;
      case IMN_PRIVATE:
        if (lParam == kNotifyUpdateUI) {
          UpdateLangBar(context, kDeferred);
          UpdateCandidate(context, kNoEvent);
        } else if (lParam == kNotifyReconvertFromIME) {
          TurnOnIMEAndTryToReconvertFromIME(hwnd_);
        } else if (lParam == kNotifyDelayedCallback) {
          SetMozcEventCallbackTimer(context);
        }
        break;
    }
    return result;
  }

  LRESULT OnSetContext(const UIContext &context, bool activated,
                       const ShowUIAttributes &show_ui_attributes) {
    // |context| might be uninitialized.  See b/3099588.
    if (context.ui_visibility_tracker() == nullptr) {
      return 0;
    }

    if (activated) {
      // The input context specified with |context| is activated.
      context.ui_visibility_tracker()->OnSetContext(show_ui_attributes);
    }
    UpdateCandidate(context, activated ? kNoEvent : kDissociateContext);
    if (activated) {
      // Invalidate the LangBar state cache because the actual state of LangBar
      // can be changed by other IMEs or applications.
      InvalidateLangBarInfoCache();
    }
    UpdateLangBar(context, kImmediate);
    return 0;
  }

  LRESULT OnControl(const UIContext &context, DWORD sub_message,
                    void *data) {
    return 0;
  }

  void OnCompositionFull(const UIContext &context) {
  }

  void OnSelect(const UIContext &context, bool select,
                HKL keyboard_layout) {
    if (!select) {
      UninitLangBar();
      return;
    }
    UpdateCandidate(context, kNoEvent);
    UpdateLangBar(context, kImmediate);

    // If the application does not allow the IME to show any UI component,
    // it would be better not to show the set default dialog.
    // We use the visibility of suggest window as a launch condition of
    // SetDefaultDialog.
    if (context.ui_visibility_tracker()->IsSuggestWindowVisible()) {
      if (!IsProcessSandboxed() && RunLevel::IsValidClientRunLevel()) {
        CallOnce(&g_launch_set_default_dialog,
                 &LaunchSetDefaultDialog);
      }
    }
  }

  LRESULT OnRequest(const UIContext &context,
                    WPARAM wParam, LPARAM lParam) {
    return 0;
  }

  LRESULT OnSessionCommand(
      HIMC himc, commands::SessionCommand::CommandType command_type,
      LPARAM lParam) {
    if (himc == nullptr) {
      return 0;
    }

    if ((command_type != commands::SessionCommand::SELECT_CANDIDATE) &&
        (command_type != commands::SessionCommand::HIGHLIGHT_CANDIDATE) &&
        (command_type != commands::SessionCommand::USAGE_STATS_EVENT)) {
      // Unsupported command.
      return 0;
    }

    if ((command_type == commands::SessionCommand::SELECT_CANDIDATE) ||
        (command_type == commands::SessionCommand::HIGHLIGHT_CANDIDATE)) {
      // Convert |mozc_candidate_id| to candidate index.
      const int32 mozc_candidate_id = static_cast<int32>(lParam);
      int candidate_index = 0;
      {
        UIContext context(himc);
        commands::Output output;
        if (!context.GetLastOutput(&output)) {
          return 0;
        }
        if (!OutputUtil::GetCandidateIndexById(
                 output, mozc_candidate_id, &candidate_index)) {
          return 0;
        }
      }  // release |context|.

      const int kCandidateWindowIndex = 0;
      if (::ImmNotifyIME(himc, NI_SELECTCANDIDATESTR, kCandidateWindowIndex,
                         candidate_index) == FALSE) {
        return 0;
      }
      if (command_type == commands::SessionCommand::SELECT_CANDIDATE) {
        if (::ImmNotifyIME(himc, NI_CLOSECANDIDATE, kCandidateWindowIndex, 0) ==
            FALSE) {
          return 0;
        }
      }
    } else if (command_type == commands::SessionCommand::USAGE_STATS_EVENT) {
      // Send USAGE_STATS_EVENT to the server.
      UIContext context(himc);
      mozc::commands::Output output;
      mozc::commands::SessionCommand command;
      mozc::commands::SessionCommand::UsageStatsEvent event =
          static_cast<mozc::commands::SessionCommand::UsageStatsEvent>(lParam);
      command.set_type(mozc::commands::SessionCommand::USAGE_STATS_EVENT);
      command.set_usage_stats_event(event);
      if (!context.client()->SendCommand(command, &output)) {
        return 0;
      }
    }
    return 1;
  }

  LRESULT UIMessageProc(const UIContext &context,
                        UINT message,
                        WPARAM wParam,
                        LPARAM lParam) {
    // A UI window should admit receiving a message even when the context is
    // empty.  You could see this situation as follows.
    //   1. Do not set Mozc as default.
    //   2. Open Notepad.
    //   3. Open Help - Version Info.
    //   4. Select Mozc in Langbar.
    // See b/2973431 and b/2970662 for details.
    if (context.IsEmpty()) {
      if ((message == WM_IME_SELECT) && (wParam == FALSE)) {
        UninitLangBar();
      } else {
        UpdateLangBar(context, kDeferred);
      }
      return 0;
    }
    switch (message) {
      case WM_IME_COMPOSITION:
        // return value will be ignored.
        OnComposition(context, (wchar_t)(wParam),
                      CompositionChangeAttributes(lParam));
        break;
      case WM_IME_COMPOSITIONFULL:
        // return value will be ignored.
        OnCompositionFull(context);
        break;
      case WM_IME_CONTROL:
        return OnControl(context, static_cast<DWORD>(wParam),
                         reinterpret_cast<void *>(lParam));
      case WM_IME_ENDCOMPOSITION:
        // return value will be ignored.
        OnEndComposition(context);
        break;
      case WM_IME_NOTIFY:
        return OnNotify(context, static_cast<DWORD>(wParam), lParam);
      case WM_IME_REQUEST:
        return OnRequest(context, wParam, lParam);
      case WM_IME_SELECT:
        // return value will be ignored.
        OnSelect(context, wParam != FALSE, (HKL)lParam);
        break;
      case WM_IME_SETCONTEXT:
        return OnSetContext(context, wParam != FALSE, ShowUIAttributes(lParam));
      case WM_IME_STARTCOMPOSITION:
        // return value will be ignored.
        OnStartComposition(context);
        break;
      case WM_IME_CHAR:
      case WM_IME_KEYDOWN:
      case WM_IME_KEYUP:
        // return value will be ignored.
        break;
      default:
        // Unknown IME_* message
        break;
    }
    // default return value
    return 0;
  }

  void OnTimer(WPARAM event_id) {
    switch (event_id) {
      case kMozcEventCallbackTimerId:
        OnDeferredMozcEventCallback();
        break;
      case kDeferredLangBarUpdateTimerId:
        OnDeferredUpdateLangBar();
        break;
    }
  }

 private:
  // Timer for the delayed callback to Mozc server.
  static const UINT_PTR kMozcEventCallbackTimerId = 1;

  // Timer for the langbar update.
  static const UINT_PTR kDeferredLangBarUpdateTimerId = 2;
  static const DWORD kLangBarUpdateDelayMilliSec = 50;

  enum LangBarUpdateMode {
    kDeferred = 0,
    kImmediate = 1,
  };

  enum IndicatorEventType {
    kNoEvent,
    kMoveFocusedWindow,
    kDissociateContext,
  };

  struct LangBarInfo {
    LangBarInfo()
        : enabled(false),
          mode(commands::DIRECT) {}

    bool enabled;
    commands::CompositionMode mode;
  };

  // Sets the timer that send callback command.
  void SetMozcEventCallbackTimer(const UIContext &context) {
    commands::Output output;
    context.GetLastOutput(&output);
    if (output.has_callback() && output.callback().has_delay_millisec()) {
      ::SetTimer(hwnd_,
                 kMozcEventCallbackTimerId,
                 output.callback().delay_millisec(),
                 NULL);
    }
  }

  // Constructs RendererCommand based on various parameters in the input
  // context.  This implementation is very experimental, should be revised.
  void UpdateCandidate(const UIContext &context,
                       IndicatorEventType indicator_event_type) {
    if (indicator_event_type != kNoEvent) {
      // We need to send UI event to the renderer anyway.
      // So the returned value from |tracker| will be ignored.
      IndicatorVisibilityTracker *tracker =
          context.indicator_visibility_tracker();
      if (tracker != nullptr) {
        switch (indicator_event_type) {
          case kMoveFocusedWindow:
            tracker->OnMoveFocusedWindow();
            break;
          case kDissociateContext:
            tracker->OnDissociateContext();
            break;
        }
      }
    }

    commands::RendererCommand command;
    command.set_type(commands::RendererCommand::UPDATE);
    command.set_visible(false);
    UpdateCommand(context, hwnd_, *context.ui_visibility_tracker(),
                  &command);
    Win32RendererClient::OnUpdated(command);
  }

  void UpdateIndicator(const UIContext &context) {
    IndicatorVisibilityTracker *tracker =
        context.indicator_visibility_tracker();
    if (tracker == nullptr) {
      return;
    }
    const IndicatorVisibilityTracker::Action action =
        tracker->OnChangeInputMode();
    if (action == IndicatorVisibilityTracker::kUpdateUI) {
      commands::RendererCommand command;
      command.set_type(commands::RendererCommand::UPDATE);
      // Initialize as invisible just in case. Basically this flag will
      // be set to true in UpdateCommand.
      command.set_visible(false);
      UpdateCommand(context, hwnd_, *context.ui_visibility_tracker(),
                    &command);
      Win32RendererClient::OnUpdated(command);
    }
  }

  bool UpdateLangBar(const UIContext &context, LangBarUpdateMode update_mode) {
    bool enabled = false;
    commands::CompositionMode mode = commands::DIRECT;

    if (context.IsEmpty()) {
      enabled = false;
      mode = commands::DIRECT;
    } else if (!context.GetOpenStatus()) {
      // Closed
      enabled = true;
      mode = commands::DIRECT;
    } else {
      DWORD imm32_visible_mode = 0;
      if (!context.GetVisibleConversionMode(&imm32_visible_mode)) {
        return false;
      }
      commands::CompositionMode mozc_mode = commands::HIRAGANA;
      if (!win32::ConversionModeUtil::ToMozcMode(imm32_visible_mode,
                                                 &mozc_mode)) {
          return false;
      }
      enabled = true;
      mode = mozc_mode;
    }

    switch (update_mode) {
      case kDeferred:
        SetDeferredLangBarUpdate(true, mode);
        break;
      case kImmediate:
        UpdateLangBarAndCancelUpdateTimer(enabled, mode);
        break;
      default:
        DCHECK(false) << "Unknown mode: " << update_mode;
        return false;
    }

    return true;
  }

  void InvalidateLangBarInfoCache() {
    langbar_info_cache_.reset(nullptr);
  }

  void SetDeferredLangBarUpdate(bool enabled, commands::CompositionMode mode) {
    CancelDeferredLangBarUpdateIfExists();

    deferred_langbar_update_request_.enabled = enabled;
    deferred_langbar_update_request_.mode = mode;
    const auto result = ::SetTimer(
        hwnd_, kDeferredLangBarUpdateTimerId,
        kLangBarUpdateDelayMilliSec, nullptr);
    if (result != 0) {
      has_pending_langbar_update_ = true;
    }
  }

  void CancelDeferredLangBarUpdateIfExists() {
    if (!has_pending_langbar_update_) {
      return;
    }
    ::KillTimer(hwnd_, kDeferredLangBarUpdateTimerId);
    has_pending_langbar_update_ = false;
  }

  void UpdateLangBarAndCancelUpdateTimer(bool enabled,
                                         commands::CompositionMode mode) {
    CancelDeferredLangBarUpdateIfExists();

    // Ensure the LangBar is initialized.
    language_bar_->InitLanguageBar(langbar_callback_);

    const bool is_redundant_call = (langbar_info_cache_.get() != nullptr &&
                                    langbar_info_cache_->enabled == enabled &&
                                    langbar_info_cache_->mode == mode);

    if (!is_redundant_call) {
      language_bar_->SetLangbarMenuEnabled(enabled);
      language_bar_->UpdateLangbarMenu(mode);
    }

    if (langbar_info_cache_.get() == nullptr) {
      langbar_info_cache_.reset(new LangBarInfo);
    }
    langbar_info_cache_->enabled = enabled;
    langbar_info_cache_->mode = mode;
  }

  void OnDeferredUpdateLangBar() {
    UpdateLangBarAndCancelUpdateTimer(deferred_langbar_update_request_.enabled,
                                      deferred_langbar_update_request_.mode);
  }

  void OnDeferredMozcEventCallback() {
    ::KillTimer(hwnd_, kMozcEventCallbackTimerId);
    const HIMC himc = GetSafeHIMC(hwnd_);
    const bool generate_message = mozc::win32::ImeCore::IsActiveContext(himc);
    ImeCore::SendCallbackCommand(himc, generate_message);
  }

  HWND hwnd_;
  // TODO(yukawa): Make a wrapper class to encapsulate LangBar implementation
  // including cache mechanism to reduce API calls.
  unique_ptr<LanguageBar> language_bar_;
  LangBarCallbackImpl *langbar_callback_;
  // Represents the LangBarInfo that should be set to the LangBar when deferred
  // timer is fired.
  LangBarInfo deferred_langbar_update_request_;
  // True while the deferred timer that updates the LangBar is scheduled.
  bool has_pending_langbar_update_;
  // Represents the last LangBarInfo that is set to the LangBar. nullpter if
  // no cached data is available.
  unique_ptr<LangBarInfo> langbar_info_cache_;

  DISALLOW_COPY_AND_ASSIGN(DefaultUIWindow);
};

// When a series of private callback messages is incoming from the renderer
// process, we might want to aggregate them mainly for performance.
// We can aggregate successive callbacks as follows.
//
// [Case 1]
//                   (Post Message Queue top)
//   [1] kMessageReceiverMessageName / HIGHLIGHT_CANDIDATE
//   [2] kMessageReceiverMessageName / HIGHLIGHT_CANDIDATE
//   [3] kMessageReceiverMessageName / HIGHLIGHT_CANDIDATE
//   [4] kMessageReceiverMessageName / SELECT_CANDIDATE
//   [5] kMessageReceiverMessageName / HIGHLIGHT_CANDIDATE
//                      any other message(s)
//   [N] kMessageReceiverMessageName / SELECT_CANDIDATE
//                      any other message(s)
//
//   In this case, messages from [1] to [3] can be removed and and start
//   handling the message [4] as if it the handler just received it.
//
//
// [Case 2]
//                   (Post Message Queue top)
//   [1] kMessageReceiverMessageName / HIGHLIGHT_CANDIDATE
//   [2] kMessageReceiverMessageName / HIGHLIGHT_CANDIDATE
//   [3] kMessageReceiverMessageName / HIGHLIGHT_CANDIDATE
//                      any other message(s)
//   [N] kMessageReceiverMessageName / HIGHLIGHT_CANDIDATE
//                      any other message(s)
//
//   In this case, messages from [1] to [2] can be removed and and start
//   handling the message [4] as if it the handler just received it.
//
//
// [Case 3]
//                   (Post Message Queue top)
//   [1] kMessageReceiverMessageName / SELECT_CANDIDATE
//   [2] kMessageReceiverMessageName / HIGHLIGHT_CANDIDATE
//                      any other message(s)
//   [N] kMessageReceiverMessageName / HIGHLIGHT_CANDIDATE
//                      any other message(s)
//
//   In this case, just start handling the message [1].
//
// This function returns the aggregated message which should be handled now.
MSG AggregateRendererCallbackMessage(
    HWND hwnd, UINT private_message, WPARAM wParam, LPARAM lParam) {
  MSG current_msg = {};
  current_msg.hwnd = hwnd;
  current_msg.message = private_message;
  current_msg.wParam = wParam;
  current_msg.lParam = lParam;

  while (true) {
    MSG next_msg = {};
    // Preview the next message from the post message queue.
    // You can avoid message dispatching from the send message queue by not
    // specifying PM_QS_SENDMESSAGE to the 5th argument.
    if (::PeekMessageW(&next_msg, hwnd, 0, 0,
                       PM_NOREMOVE | PM_QS_POSTMESSAGE | PM_NOYIELD) == 0) {
      // No message is in the queue.
      // |current_msg| is what we should handle now.
      return current_msg;
    }

    if (next_msg.message != private_message) {
      // The next message is not a private renderer callback message.
      // |current_msg| is what we should handle now.
      return current_msg;
    }

    // OK, the next message is a private renderer callback.
    // Remove this message from the post message queue.
    MSG removed_msg = {};
    if (::PeekMessageW(&removed_msg, hwnd, private_message, private_message,
                       PM_REMOVE | PM_QS_POSTMESSAGE | PM_NOYIELD) == 0) {
      // Something wrong.
      // give up aggregating the message.
      return current_msg;
    }

    current_msg = next_msg;
    const mozc::commands::SessionCommand::CommandType command_type =
        static_cast<mozc::commands::SessionCommand::CommandType>(
            current_msg.wParam);

    // If this is a HIGHLIGHT_CANDIDATE message, resume aggregation.
    if (command_type ==
        mozc::commands::SessionCommand::HIGHLIGHT_CANDIDATE) {
      continue;
    }

    return current_msg;
  }
}

LRESULT WINAPI UIWindowProc(HWND hwnd,
                            UINT message,
                            WPARAM wParam,
                            LPARAM lParam) {
  DANGLING_CALLBACK_GUARD(0);

  const bool is_ui_message =
      (::ImmIsUIMessage(nullptr, message, wParam, lParam) != FALSE);

  // Create UI window object and associate it to the window.
  if (message == WM_NCCREATE) {
    if (mozc::win32::IsInLockdownMode() ||
        !mozc::RunLevel::IsValidClientRunLevel()) {
      // Clear Kana-lock state not to prevent users from typing their
      // correct passwords.
      // TODO(yukawa): Move this code to somewhere appropriate.
      BYTE keyboard_state[256] = {};
      if (::GetKeyboardState(keyboard_state) != FALSE) {
        keyboard_state[VK_KANA] = 0;
        ::SetKeyboardState(keyboard_state);
      }

      // Return FALSE not to be activated if the current session is
      // WinLogon. It may reduce the risk of BSOD.
      return FALSE;
    }

    DefaultUIWindow* ui_window = new DefaultUIWindow(hwnd);

    ::SetWindowLongPtr(hwnd,
                       IMMGWLP_PRIVATE,
                       reinterpret_cast<LONG_PTR>(ui_window));

    Singleton<PrivateRendererMessageInitializer>::get()->Initialize(hwnd);
  }
  // Retrieves UI window object from the private area.
  DefaultUIWindow* ui_window = reinterpret_cast<DefaultUIWindow*>(
      ::GetWindowLongPtrW(hwnd, IMMGWLP_PRIVATE));

  if (ui_window == nullptr) {
    if (is_ui_message) {
      return 0;
    } else {
      return ::DefWindowProc(hwnd, message, wParam, lParam);
    }
  }

  LRESULT result = 0;
  const bool is_renderer_message =
      Singleton<PrivateRendererMessageInitializer>::get()->
          IsPrivateRendererMessage(message);

  bool is_handled = false;
  if (is_ui_message) {
    const HIMC himc = GetSafeHIMC(hwnd);
    result = ui_window->UIMessageProc(UIContext(himc),
                                      message, wParam, lParam);
    is_handled = true;
  } else if (is_renderer_message) {
    const MSG renderer_msg = AggregateRendererCallbackMessage(
        hwnd, message, wParam, lParam);
    const mozc::commands::SessionCommand::CommandType command_type =
        static_cast<mozc::commands::SessionCommand::CommandType>(
            renderer_msg.wParam);
    const HIMC himc = GetSafeHIMC(hwnd);
    result = ui_window->OnSessionCommand(himc, command_type,
                                         renderer_msg.lParam);
    is_handled = true;
  } else if (message == WM_DESTROY) {
    // Ensure the LangBar is uninitialized.
    ui_window->UninitLangBar();
  } else if (message == WM_NCDESTROY) {
    Win32RendererClient::OnUIThreadUninitialized();

    // Delete UI window object if the window is destroyed.
    ::SetWindowLongPtr(hwnd, IMMGWLP_PRIVATE, 0);
    delete ui_window;
  } else if (message == WM_TIMER) {
    ui_window->OnTimer(wParam);
    // In order to reduce the potential risk of shatter attack, we don't want
    // to pass the WM_TIMER to ::DefWindowProc.
    is_handled = true;
  }
  if (!is_handled) {
    result = ::DefWindowProcW(hwnd, message, wParam, lParam);
    is_handled = true;
  }
  return result;
}

}  // namespace

bool UIWindowManager::OnDllProcessAttach(HINSTANCE module_handle,
                                         bool static_loading) {
  WNDCLASSEXW wc = {};
  wc.cbSize = sizeof(WNDCLASSEX);
  wc.style = CS_IME;
  wc.lpfnWndProc = UIWindowProc;
  wc.cbWndExtra = 2 * sizeof(LONG_PTR);
  wc.hInstance = module_handle;
  wc.lpszClassName = kIMEUIWndClassName;

  const ATOM atom = ::RegisterClassExW(&wc);
  if (atom == INVALID_ATOM) {
    const DWORD error = ::GetLastError();
    return false;
  }

  Win32RendererClient::OnModuleLoaded(module_handle);
  return true;
}

void UIWindowManager::OnDllProcessDetach(HINSTANCE module_handle,
                                         bool process_shutdown) {
  if (::UnregisterClass(kIMEUIWndClassName, module_handle) == 0) {
    // Sometimes the IME DLL is unloaded before all the UI message windows
    // which belong to the DLL are destroyed.  In such a situation, we cannot
    // unregister window class. See b/4271156.
  }
  // This flag is used to inactivate out DefWindowProc and any other callbacks
  // to avoid further problems.
  g_module_unloaded = true;
  Win32RendererClient::OnModuleUnloaded();
}

}  // namespace win32
}  // namespace mozc
