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

// An implementation of the IMM32 interface.
//

#include "win32/ime/ime_impl_imm.h"

#include <ime.h>

#include <strsafe.h>

#include "google/protobuf/stubs/common.h"
#include "base/const.h"
#include "base/crash_report_handler.h"
#include "base/logging.h"
#include "base/process.h"
#include "base/singleton.h"
#include "base/system_util.h"
#include "base/update_util.h"
#include "base/util.h"
#include "config/stats_config_util.h"
#include "win32/base/browser_info.h"
#include "win32/base/conversion_mode_util.h"
#include "win32/base/deleter.h"
#include "win32/base/focus_hierarchy_observer.h"
#include "win32/base/indicator_visibility_tracker.h"
#include "win32/base/immdev.h"
#include "win32/base/input_state.h"
#include "win32/base/string_util.h"
#include "win32/base/surrogate_pair_observer.h"
#include "win32/ime/ime_candidate_info.h"
#include "win32/ime/ime_composition_string.h"
#include "win32/ime/ime_core.h"
#include "win32/ime/ime_input_context.h"
#include "win32/ime/ime_message_queue.h"
#include "win32/ime/ime_private_context.h"
#include "win32/ime/ime_scoped_context.h"
#include "win32/ime/ime_ui_context.h"
#include "win32/ime/ime_ui_visibility_tracker.h"
#include "win32/ime/ime_ui_window.h"

namespace {

HINSTANCE g_instance = nullptr;
DWORD g_ime_system_info = MAXDWORD;
// True if the boot mode is safe mode.
bool g_in_safe_mode = true;
// True when SystemUtil::EnsureVitalImmutableDataIsAvailable() returns false.
bool g_fundamental_data_is_not_available = false;

// TLS index for context update count. See b/3282221 for details.
const DWORD kInvalidTlsIndex = 0xffffffff;
DWORD g_context_revision_tls_index = kInvalidTlsIndex;

// Breakpad never be enabled except for official builds.
#if defined(GOOGLE_JAPANESE_INPUT_BUILD)
#define USE_BREAKPAD
#endif  // GOOGLE_JAPANESE_INPUT_BUILD

#if defined(USE_BREAKPAD)
// A critical section object for breakpad because its initialization routine is
// not thread-safe.  See b/3100365 why we need this.
CRITICAL_SECTION g_critical_section_for_breakpad;
// 4,000 is a typical value of per-heap critical sections.
// See http://msdn.microsoft.com/en-us/library/ms683476.aspx
const int kSpinCountForCriticalSection = 4000;
#endif  // USE_BREAKPAD

// True if the DLL received DLL_PROCESS_DETACH notification as a result of
// process shutting down.  If this bit is true, you must not call any
// function exported from other DLLs nor function implemented by CRT because
// they might also have been uninitialized.
bool g_process_is_shutting_down = false;

// Some troublesome DLLs such as msctf.dll on XP may violate the rule that
// a DLL should not call functions exported from other DLLs except for
// kernel32.dll in DllMain.  As a result, function in other DLLs including
// this DLL might be called even after it received DLL_PROCESS_DETACH
// notification.  You are likely to notice this issue especially on
// CUAS-enabled XP, as filed in b/3088049.
// This macro can be used to mitigate this scenario.
#define DANGLING_CALLBACK_GUARD(return_code)   \
  do {                                         \
    if (g_process_is_shutting_down) {          \
      return (return_code);                    \
    }                                          \
  } while (false)

static_assert(arraysize(mozc::kIMEUIWndClassName)
              <= mozc::kIMEUIwndClassNameLimitInTchars,
              "Window Class Name has length limit.");

// Maximum number of characters for |REGISTERWORD::lpWord| and
// |REGISTERWORD::lpReading|.
const size_t kMaxCharsForRegisterWord = 64;

// If given string is too long, returns an empty string instead.
wstring GetStringIfWithinLimit(const wchar_t *src, size_t size_limit) {
  if (src == nullptr) {
    return wstring();
  }
  for (size_t i = 0; i < size_limit; ++i) {
    if (src[i] == L'\0') {
      return wstring(src, i);
    }
  }
  return wstring();
}

void SetEnveronmentVariablesForWordRegisterDialog(
    const wstring &word_value, const wstring &word_reading) {
  wstring word_value_env_name;
  wstring word_reading_env_name;
  mozc::Util::UTF8ToWide(
      mozc::kWordRegisterEnvironmentName, &word_value_env_name);
  mozc::Util::UTF8ToWide(
      mozc::kWordRegisterEnvironmentReadingName, &word_reading_env_name);

  if (word_value.empty()) {
    // Remove relevant variables.
    ::SetEnvironmentVariable(word_value_env_name.c_str(), nullptr);
    ::SetEnvironmentVariable(word_reading_env_name.c_str(), nullptr);
  }

  ::SetEnvironmentVariable(word_value_env_name.c_str(),
                           word_value.c_str());
  if (word_reading.empty()) {
    // Remove relevant variable.
    ::SetEnvironmentVariable(word_reading_env_name.c_str(),
                             nullptr);
  } else {
    ::SetEnvironmentVariable(word_reading_env_name.c_str(),
                             word_reading.c_str());
  }
}

static HIMCC InitializeHIMCC(HIMCC himcc, DWORD size) {
  if (himcc == nullptr) {
    return ::ImmCreateIMCC(size);
  } else {
    return ::ImmReSizeIMCC(himcc, size);
  }
}

int32 GetContextRevision() {
  if (g_context_revision_tls_index == kInvalidTlsIndex) {
    return 0;
  }
  const int32 revision =
    reinterpret_cast<int32>(::TlsGetValue(g_context_revision_tls_index));
  return revision;
}

void IncrementContextRevision() {
  if (g_context_revision_tls_index == kInvalidTlsIndex) {
    return;
  }
  const int32 next_age = GetContextRevision() + 1;
  TlsSetValue(g_context_revision_tls_index, reinterpret_cast<void *>(next_age));
}

void FillContext(HIMC himc, mozc::commands::Context *context) {
  if (context == nullptr) {
    return;
  }
  context->set_revision(GetContextRevision());

  if (himc == nullptr) {
    return;
  }
  const INPUTCONTEXT *input_context = ::ImmLockIMC(himc);
  mozc::win32::ScopedHIMCC<mozc::win32::PrivateContext>
      private_context(input_context->hPrivate);
  const HWND attached_window = input_context->hWnd;
  ::ImmUnlockIMC(himc);

  const auto &focus_hierarchy_observer =
      *private_context->focus_hierarchy_observer;
  if (focus_hierarchy_observer.IsAbailable()) {
    if (mozc::win32::BrowserInfo::IsOnChromeOmnibox(focus_hierarchy_observer)) {
      context->add_experimental_features("chrome_omnibox");
    }
  }
}

}  // namespace

HINSTANCE ImeGetResource() {
  return g_instance;
}

namespace mozc {
namespace win32 {
bool IsInLockdownMode() {
  if (g_in_safe_mode) {
    return true;
  }
  if ((g_ime_system_info & IME_SYSINFO_WINLOGON) == IME_SYSINFO_WINLOGON) {
    return true;
  }
  if (g_fundamental_data_is_not_available) {
    return true;
  }
  return false;
}

BOOL OnDllProcessAttach(HINSTANCE instance, bool static_loading) {
  g_instance = instance;
#if defined(USE_BREAKPAD)
  if (!::InitializeCriticalSectionAndSpinCount(&g_critical_section_for_breakpad,
                                              kSpinCountForCriticalSection)) {
    return FALSE;
  }
  mozc::CrashReportHandler::SetCriticalSection(
      &g_critical_section_for_breakpad);
#endif  // USE_BREAKPAD

  BrowserInfo::OnDllProcessAttach(instance, static_loading);
  FocusHierarchyObserver::OnDllProcessAttach(instance, static_loading);

  if (!UIWindowManager::OnDllProcessAttach(instance, static_loading)) {
    return FALSE;
  }

  if (g_context_revision_tls_index == kInvalidTlsIndex) {
    g_context_revision_tls_index = ::TlsAlloc();
  }
  return TRUE;
}

BOOL OnDllProcessDetach(HINSTANCE instance, bool process_shutdown) {
  if (g_context_revision_tls_index != kInvalidTlsIndex) {
    ::TlsFree(g_context_revision_tls_index);
    g_context_revision_tls_index = kInvalidTlsIndex;
  }

  UIWindowManager::OnDllProcessDetach(instance, process_shutdown);
  FocusHierarchyObserver::OnDllProcessDetach(instance, process_shutdown);
  BrowserInfo::OnDllProcessDetach(instance, process_shutdown);

  g_instance = nullptr;

  if (!g_in_safe_mode) {
    // It is our responsibility to make sure that our code never touch protobuf
    // library after google::protobuf::ShutdownProtobufLibrary is called.
    // Unfortunately, DllMain is the only place that satisfies this condition.
    // So we carefully call it here, even though DllMain is expected to be
    // dangerous for potential deadlocks.  See b/2126375 for details.
    google::protobuf::ShutdownProtobufLibrary();
  }

  if (process_shutdown) {
    g_process_is_shutting_down |= true;
  }

#if defined(USE_BREAKPAD)
  mozc::CrashReportHandler::SetCriticalSection(nullptr);
  ::DeleteCriticalSection(&g_critical_section_for_breakpad);
#endif  // USE_BREAKPAD

  return TRUE;
}
}  // namespace win32
}  // namespace mozc

BOOL WINAPI ImeInquire(LPIMEINFO ime_info,
                       LPTSTR class_name,
                       DWORD system_info_flags) {
  // Cache the boot mode here so that we need not call user32.dll functions
  // from DllMain.  If it is safe mode, we omit some initializations/
  // uninitializations to reduce potential crashes around them. (b/2728123)
  // 0: Normal boot
  // 1: Fail-safe boot
  // 2: Fail-safe with network boot
  g_in_safe_mode = (::GetSystemMetrics(SM_CLEANBOOT) > 0);
  if (g_in_safe_mode) {
    // Fail immediately in safe mode
    return FALSE;
  }

  ::ZeroMemory(ime_info, sizeof(IMEINFO));

  // Although |IME_PROP_NO_KEYS_ON_CLOSE| might be beneficial from performance
  // perspective, we actually have to check all key events, even when the IME
  // is turned off, to allow users to use an arbitrary key combination to turn
  // on IME.
  ime_info->fdwProperty = 0
      | IME_PROP_END_UNLOAD
      | IME_PROP_KBD_CHAR_FIRST
      | IME_PROP_ACCEPT_WIDE_VKEY
      | IME_PROP_AT_CARET
      | IME_PROP_NEED_ALTKEY
      | IME_PROP_CANDLIST_START_FROM_1
      | IME_PROP_UNICODE;

#if !defined(UNICODE)
  // Actually, we have never tested on non-unicode build.
#error "Non-Unicode build is not supported.";
#endif  // !UNICODE

  ime_info->fdwConversionCaps = IME_CMODE_LANGUAGE
                              | IME_CMODE_KATAKANA
                              | IME_CMODE_FULLSHAPE
                              | IME_CMODE_ROMAN;

  // Currently, only IME_SMODE_PHRASEPREDICT is supported.
  // See b/2913510, b/2954777, and b/2955175 for details.
  ime_info->fdwSentenceCaps = IME_SMODE_PHRASEPREDICT;

  ime_info->fdwUICaps = UI_CAP_2700;

  ime_info->fdwSCSCaps = SCS_CAP_MAKEREAD
                       | SCS_CAP_SETRECONVERTSTRING;

  ime_info->fdwSelectCaps = SELECT_CAP_CONVERSION
                          | SELECT_CAP_SENTENCE;

  const PTSTR strcpy_result =
      lstrcpyn(class_name, mozc::kIMEUIWndClassName,
               mozc::kIMEUIwndClassNameLimitInTchars);

  if (!strcpy_result) {
    return FALSE;
  }

  g_ime_system_info = system_info_flags;
  if (!mozc::SystemUtil::EnsureVitalImmutableDataIsAvailable()) {
    // This process might be sandboxed.
    g_fundamental_data_is_not_available = true;
  }

  if (!mozc::win32::IsInLockdownMode()) {
#if defined(USE_BREAKPAD)
    if (mozc::config::StatsConfigUtil::IsEnabled()) {
      mozc::CrashReportHandler::Initialize(true);
    }
#endif  // USE_BREAKPAD
  }

  return TRUE;
}

DWORD WINAPI ImeConversionList(HIMC himc,
                               LPCTSTR source,
                               LPCANDIDATELIST candidate_list,
                               DWORD buffer_length,
                               UINT flags) {
  DANGLING_CALLBACK_GUARD(FALSE);
  return 0;
}

BOOL WINAPI ImeDestroy(UINT force) {
  DANGLING_CALLBACK_GUARD(FALSE);
  // Free all singleton instances
  mozc::SingletonFinalizer::Finalize();

  // We deliberately call google::protobuf::ShutdownProtobufLibrary from
  // OnDllProcessDetach rather than here.  See b/2126375 for details.

#if defined(USE_BREAKPAD)
  if (mozc::CrashReportHandler::IsInitialized()) {
    // Uninitialize the breakpad.
    mozc::CrashReportHandler::Uninitialize();
  }
#endif  // !USE_BREAKPAD

  return TRUE;
}

LRESULT WINAPI ImeEscape(HIMC himc, UINT sub_func, LPVOID data) {
  DANGLING_CALLBACK_GUARD(FALSE);
  switch (sub_func) {
    case IME_ESC_IME_NAME: {
      // Application wants to retrieve the name of the IME.
      // Currently, we returns English name.
      // According to the document, the buffer is guaranteed to be greater
      // than or equal to 64 characters in Windows NT.
      // http://msdn.microsoft.com/en-us/library/dd318166.aspx
      wstring name;
      mozc::Util::UTF8ToWide(mozc::kProductNameInEnglish, &name);
      wchar_t *dest = static_cast<wchar_t *>(data);
      const HRESULT result = ::StringCchCopyN(
          dest,
          mozc::kSafeIMENameLengthForNTInTchars,
          name.c_str(),
          mozc::kSafeIMENameLengthForNTInTchars);
      return (SUCCEEDED(result) ? TRUE : FALSE);
    }
    default:
      // not implemented
      return FALSE;
  }
  return FALSE;
}

BOOL WINAPI ImeSetActiveContext(HIMC himc, BOOL flag) {
  DANGLING_CALLBACK_GUARD(FALSE);
  // Clear kana-lock state so that users can input their passwords.
  // TODO(yukawa): Move this code to somewhere appropriate.
  BYTE keyboard_state[256];
  ::GetKeyboardState(keyboard_state);
  keyboard_state[VK_KANA] = 0;
  ::SetKeyboardState(keyboard_state);

  // Occasionally this function is called with nullptr in |himc|.
  if (himc == nullptr) {
    return TRUE;
  }

  const bool activated = (flag != FALSE);

  // A temporal workaround for b/3046497.  Occasionally ImmLockIMC fails
  // to lock the context.
  // TODO(yukawa): Refactor HIMCLockerT to support this scenario.
  {
    INPUTCONTEXT *context = ::ImmLockIMC(himc);
    if (context == nullptr) {
      return FALSE;
    }

    // Clear |INPUTCONTEXT::hWnd| so that IMM subsystem will not generate UI
    // messages when a deactivated input contexts is specified.
    // Background:
    //   It seems that IMM does not clear |INPUTCONTEXT::hWnd| by default when
    //   an input context is about being deactivated.  However, an application
    //   still can access to a deactivated input context via IMM APIs such as
    //   ImmSetOpenStatus and IMM subsystem generates UI messages as long as
    //   the |INPUTCONTEXT::hWnd| contains a valid window handle.
    if (!activated) {
      context->hWnd = nullptr;
    }
    ::ImmUnlockIMC(himc);
  }

  mozc::win32::ScopedHIMC<mozc::win32::InputContext> context(himc);
  if (!mozc::win32::PrivateContextUtil::IsValidPrivateContext(
           context->hPrivate)) {
    return FALSE;
  }
  mozc::win32::ScopedHIMCC<mozc::win32::PrivateContext>
      private_context(context->hPrivate);

  mozc::win32::MessageQueue message_queue(himc);
  if (activated) {
    private_context->ui_visibility_tracker->OnFocus();
  } else {
    private_context->ui_visibility_tracker->OnBlur();
  }
  message_queue.AddMessage(
      WM_IME_NOTIFY, IMN_PRIVATE, mozc::win32::kNotifyUpdateUI);

  return (message_queue.Send() ? TRUE : FALSE);
}

BOOL WINAPI ImeProcessKey(HIMC himc,
                          UINT virtual_key,
                          LPARAM lParam,
                          CONST LPBYTE key_state) {
  DANGLING_CALLBACK_GUARD(FALSE);
  if (!mozc::win32::ImeCore::IsInputContextInitialized(himc)) {
    return FALSE;
  }

  mozc::win32::ScopedHIMC<mozc::win32::InputContext> context(himc);
  mozc::win32::ScopedHIMCC<mozc::win32::PrivateContext>
      private_context(context->hPrivate);

  // Because of IME_PROP_ACCEPT_WIDE_VKEY, |HIWORD(virtual_key)| contains an
  // Unicode character if |HIWORD(virtual_key) == VK_PACKET|.
  // You cannot assume that |virtual_key| is in [0, 255].
  mozc::win32::VirtualKey vk =
      mozc::win32::VirtualKey::FromCombinedVirtualKey(virtual_key);

  const mozc::win32::KeyboardStatus keyboard_status(key_state);
  const mozc::win32::LParamKeyInfo key_info(lParam);

  // Check if this key event is handled by VKBackBasedDeleter to support
  // *deletion_range* rule.
  const mozc::win32::VKBackBasedDeleter::ClientAction vk_back_action =
      private_context->deleter->OnKeyEvent(
          vk.virtual_key(), key_info.IsKeyDownInImeProcessKey(), true);
  switch (vk_back_action) {
    case mozc::win32::VKBackBasedDeleter::DO_DEFAULT_ACTION:
      // do nothing.
      break;
    case mozc::win32::VKBackBasedDeleter::
             CALL_END_DELETION_THEN_DO_DEFAULT_ACTION:
      private_context->deleter->EndDeletion();
      break;
    case mozc::win32::VKBackBasedDeleter::SEND_KEY_TO_APPLICATION:
      return FALSE;  // Do not consume this key.
    case mozc::win32::VKBackBasedDeleter::CONSUME_KEY_BUT_NEVER_SEND_TO_SERVER:
      return TRUE;  // Consume this key but do not send this key to server.
    case mozc::win32::VKBackBasedDeleter::
             CALL_END_DELETION_BUT_NEVER_SEND_TO_SERVER:
    case mozc::win32::VKBackBasedDeleter::APPLY_PENDING_STATUS:
    default:
      DLOG(FATAL) << "this action is not applicable to ImeProcessKey.";
      break;
  }

  if (context->fOpen) {
    const mozc::win32::SurrogatePairObserver::ClientAction surrogate_action =
        private_context->surrogate_pair_observer->OnTestKeyEvent(
            vk, key_info.IsKeyDownInImeProcessKey());
    switch (surrogate_action.type) {
      case mozc::win32::SurrogatePairObserver::DO_DEFAULT_ACTION:
        break;
      case mozc::win32::SurrogatePairObserver::
          DO_DEFAULT_ACTION_WITH_RETURNED_UCS4:
        vk = mozc::win32::VirtualKey::FromUnicode(surrogate_action.ucs4);
        break;
      case mozc::win32::SurrogatePairObserver::
          CONSUME_KEY_BUT_NEVER_SEND_TO_SERVER:
        return TRUE;  // Consume this key but do not send this key to server.
      default:
        DLOG(FATAL) << "this action is not applicable to ImeProcessKey.";
        break;
    }
  }

  mozc::win32::InputState ime_state = *private_context->ime_state;

  // Update |private_context->ime_behavior| to support Kana/Roman input toggle
  // keys.  See b/3118905 for details.
  mozc::win32::KeyEventHandler::UpdateBehaviorInImeProcessKey(
      vk, key_info.IsKeyDownInImeProcessKey(),
      ime_state, private_context->ime_behavior);

  // Make an snapshot of |private_context->ime_behavior|, which
  // cannot be substituted for by const reference.
  mozc::win32::InputBehavior behavior = *private_context->ime_behavior;
  mozc::commands::Context mozc_context;
  FillContext(himc, &mozc_context);

  ime_state.logical_conversion_mode = context->fdwConversion;
  ime_state.open = (context->fOpen != FALSE);
  mozc::win32::InputState next_state;
  mozc::commands::Output temporal_output;
  const mozc::win32::KeyEventHandlerResult result =
      mozc::win32::ImeCore::ImeProcessKey(private_context->client,
          vk, key_info, keyboard_status, behavior, ime_state, mozc_context,
          &next_state, &temporal_output);
  if (!result.succeeded) {
    return FALSE;
  }

  *private_context->ime_state = next_state;

  if (result.should_be_sent_to_server && temporal_output.has_consumed()) {
    private_context->last_output->CopyFrom(temporal_output);
  }

  const mozc::win32::IndicatorVisibilityTracker::Action indicator_action =
      private_context->indicator_visibility_tracker->
          OnTestKey(vk, key_info.IsKeyDownInImeProcessKey(),
                    result.should_be_eaten);
  if (indicator_action == mozc::win32::IndicatorVisibilityTracker::kUpdateUI) {
    mozc::win32::MessageQueue message_queue(himc);
    message_queue.AddMessage(
        WM_IME_NOTIFY, IMN_PRIVATE, mozc::win32::kNotifyUpdateUI);
    message_queue.Send();
  }

  return result.should_be_eaten ? TRUE : FALSE;
}

// TODO(yukawa): Refactor the implementation.
BOOL WINAPI NotifyIME(HIMC himc, DWORD action, DWORD index, DWORD value) {
  DANGLING_CALLBACK_GUARD(FALSE);
  if (!mozc::win32::ImeCore::IsInputContextInitialized(himc)) {
    return FALSE;
  }

  const bool generate_message = mozc::win32::ImeCore::IsActiveContext(himc);

  switch (action) {
    case NI_CLOSECANDIDATE: {
      const DWORD candidate_window_index = index;
      if (candidate_window_index != 0) {
        return FALSE;
      }
      return mozc::win32::ImeCore::CloseCandidate(himc, generate_message);
    }
    case NI_SELECTCANDIDATESTR: {
      const DWORD candidate_window_index = index;
      if (candidate_window_index != 0) {
        return FALSE;
      }
      const int32 candidate_index = static_cast<int32>(value);
      return mozc::win32::ImeCore::HighlightCandidate(
          himc, candidate_index, generate_message);
    }
    case NI_OPENCANDIDATE:
    case NI_CHANGECANDIDATELIST:
    case NI_FINALIZECONVERSIONRESULT:
    case NI_SETCANDIDATE_PAGESTART:
    case NI_SETCANDIDATE_PAGESIZE:
    case NI_IMEMENUSELECTED:
      // not implemented
      // TODO(yukawa): implement them.
      return FALSE;
  }

  if (action == NI_COMPOSITIONSTR) {
    mozc::win32::UIContext context(himc);
    if (context.IsCompositionStringEmpty()) {
      return TRUE;
    }

    switch (index) {
      case CPS_COMPLETE: {
        if (!mozc::win32::ImeCore::SubmitComposition(
                himc, generate_message)) {
          return FALSE;
        }
        return TRUE;
      }
      case CPS_CANCEL: {
        if (!mozc::win32::ImeCore::CancelComposition(
                himc, generate_message)) {
          return FALSE;
        }
        return TRUE;
      }
      case CPS_REVERT:
      case CPS_CONVERT:
        // not implemented
        // TODO(yukawa): implement them.
        return FALSE;
      default:
        return FALSE;
    }
    // never reaches here.
    CHECK(FALSE);
  }

  if (action != NI_CONTEXTUPDATED) {
    return FALSE;
  }

  CHECK_EQ(NI_CONTEXTUPDATED, action);

  switch (value) {
    case IMC_SETCONVERSIONMODE: {
      mozc::win32::ScopedHIMC<mozc::win32::InputContext> context(himc);
      context->fdwConversion =
          mozc::win32::ImeCore::GetSupportableConversionMode(
              context->fdwConversion);
      mozc::win32::ImeCore::SwitchInputMode(
          himc, context->fdwConversion, generate_message);
      // We need not to generate WM_IME_NOTIFY/IMN_SETSENTENCEMODE because
      // ImmSetOpenStatus API generates it anyway.
      return TRUE;
    }
    case IMC_SETSENTENCEMODE: {
      // See b/2913510, b/2954777, and b/2955175 for details.
      mozc::win32::ScopedHIMC<mozc::win32::InputContext> context(himc);
      // We need not to generate WM_IME_NOTIFY/IMN_SETSENTENCEMODE because
      // ImmSetOpenStatus API generates it anyway.
      context->fdwSentence =
          mozc::win32::ImeCore::GetSupportableSentenceMode(
              context->fdwSentence);
      return TRUE;
    }
    case IMC_SETOPENSTATUS: {
      mozc::win32::UIContext context(himc);
      if (!context.GetOpenStatus()) {
        // If this is an active context, we have to generate message because
        // ImmSetOpenStatus API is responsible for generating only
        // a WM_IME_NOTIFY(IMC_SETOPENSTATUS) message.  Any other UI messages
        // including composition messages should be delivered when an on-going
        // composition is terminated.  See b/3186132 for details.
        mozc::win32::ImeCore::IMEOff(himc, generate_message);
        return TRUE;
      }

      DCHECK(context.GetOpenStatus());
      DWORD mode = 0;
      if (!context.GetConversionMode(&mode)) {
        return FALSE;
      }
      // This is OK because ImeCore::OpenIME generates no UI messages.
      mozc::win32::ImeCore::OpenIME(context.client(), mode);
      // We need not to generate WM_IME_NOTIFY/IMN_SETOPENSTATUS because
      // ImmSetOpenStatus API generates it anyway.
      return TRUE;
    }
    case IMC_SETCANDIDATEPOS:
    case IMC_SETCOMPOSITIONFONT:
    case IMC_SETCOMPOSITIONWINDOW:
      // We need not to generate corresponding UI messages because Imm API
      // generate it anyway.
      return TRUE;
    default:
      return FALSE;
  }
  return FALSE;
}

// We need not to generate any UI message in this callback.
// UI window is responsible for updating its UI when it receives
// WM_IME_SETCONTEXT.
BOOL WINAPI ImeSelect(HIMC himc, BOOL select) {
  DANGLING_CALLBACK_GUARD(FALSE);
  // Clear kana-lock state so that users can input their passwords.
  // TODO(yukawa): Move this code to somewhere appropriate.
  BYTE keyboard_state[256];
  ::GetKeyboardState(keyboard_state);
  keyboard_state[VK_KANA] = 0;
  ::SetKeyboardState(keyboard_state);

  // In "lockdown" mode, it would be definitely better do nothing in our DLL.
  // For example, lots of fundamental stop working in a sandboxed process as
  // reported in b/3216603.  In such a situation, remaining CHECK macro is
  // likely to cause process crash.
  if (mozc::win32::IsInLockdownMode()) {
    return FALSE;
  }

  IncrementContextRevision();

  if (himc == nullptr) {
    return TRUE;
  }

  if (select == FALSE) {
    // If there exist any on-going composition, IMM32 automatically calls
    // NotifyIME with CPS_CANCEL or CPS_COMPLETE in advance based on
    // IME_PROP_COMPLETE_ON_UNSELECT property.
    // You need not to submit nor cancel composition here.

    // Clean up resources in PrivateContext.
    mozc::win32::ScopedHIMC<INPUTCONTEXT> context(himc);
    if (mozc::win32::PrivateContextUtil::IsValidPrivateContext(
            context->hPrivate)) {
      mozc::win32::ScopedHIMCC<mozc::win32::PrivateContext>
          private_context(context->hPrivate);
      private_context->Uninitialize();
    }
    return TRUE;
  }

  // Unfortunately, InitLogStream cannot be placed inside DllMain because it
  // may internally call LoadSystemLibrary to retrieve user profile directory.
  // We should definitely avoid using LoadSystemLibrary when the thread owns
  // loader lock.
  mozc::Logging::InitLogStream(kProductPrefix "_imm32_ui");

  mozc::win32::ScopedHIMC<mozc::win32::InputContext> context(himc);
  if (context.get() == nullptr) {
    return FALSE;
  }

  if (!context->Initialize()) {
    return FALSE;
  }

  // If the private area of the input context is not initialized,
  // allocate the new region in which new client management object is
  // stored.
  if (!mozc::win32::PrivateContextUtil::EnsurePrivateContextIsInitialized(
           &context->hPrivate)) {
    return FALSE;
  }

  mozc::win32::ScopedHIMCC<mozc::win32::PrivateContext>
      private_context(context->hPrivate);
  DCHECK(private_context->Validate());

  // Normalize the conversion mode.
  context->fdwConversion = mozc::win32::ImeCore::GetSupportableConversionMode(
      context->fdwConversion);

  // Then, copy the initial mode into private context.
  private_context->ime_state->logical_conversion_mode = context->fdwConversion;
  private_context->ime_state->visible_conversion_mode = context->fdwConversion;

  // Allocate composition string buffer.
  const HIMCC composition_string_handle = InitializeHIMCC(
      context->hCompStr, sizeof(mozc::win32::CompositionString));
  if (composition_string_handle == nullptr) {
    return FALSE;
  }
  mozc::win32::ScopedHIMCC<mozc::win32::CompositionString>
      composition_string(composition_string_handle);
  if (!composition_string->Initialize()) {
    return FALSE;
  }

  context->hCandInfo =
      mozc::win32::CandidateInfoUtil::Initialize(context->hCandInfo);
  if (context->hCandInfo == nullptr) {
    return FALSE;
  }

  // When this is an active context, notify it because ImeSetActiveContext will
  // not be called when IME is changed.
  if (mozc::win32::ImeCore::IsActiveContext(himc)) {
    private_context->ui_visibility_tracker->OnFocus();
  }

  // Sync initial focus hierarchy.
  private_context->focus_hierarchy_observer->SyncFocusHierarchy();

  // Send the local status to the server when IME is ON.
  if (context->fOpen) {
    if ((context->fdwInit & INIT_CONVERSION) != INIT_CONVERSION) {
      return FALSE;
    }
    // This is OK because ImeCore::OpenIME does not generate any UI message.
    if (!mozc::win32::ImeCore::OpenIME(
             private_context->client, context->fdwConversion)) {
      return FALSE;
    }
  }

  // Write a registry value for usage tracking by Omaha.
  // We ignore the returned value by the function because we should not disturb
  // the application by the result of this function.
  if (!mozc::UpdateUtil::WriteActiveUsageInfo()) {
    LOG(WARNING) << "WriteActiveUsageInfo failed";
  }

  return TRUE;
}

BOOL WINAPI ImeSetCompositionString(HIMC himc,
                                    DWORD index,
                                    LPVOID comp,
                                    DWORD comp_length,
                                    LPVOID read,
                                    DWORD read_length) {
  DANGLING_CALLBACK_GUARD(FALSE);
  if (index == SCS_QUERYRECONVERTSTRING) {
    // In this case, IMEs are supposed to update |composition_info| and/or
    // |reading_info| if necessary.
    RECONVERTSTRING *composition_info =
        reinterpret_cast<RECONVERTSTRING *>(comp);
    RECONVERTSTRING *reading_info =
        reinterpret_cast<RECONVERTSTRING *>(read);
    return mozc::win32::ImeCore::QueryReconversionFromApplication(
        himc, composition_info, reading_info);
  } else if (index == SCS_SETRECONVERTSTRING) {
    // In this case, IMEs must not update |composition_info| nor
    // |reading_info|.  This is why they are treated as const pointer.
    const RECONVERTSTRING *composition_info =
        reinterpret_cast<const RECONVERTSTRING *>(comp);
    const RECONVERTSTRING *reading_info =
        reinterpret_cast<const RECONVERTSTRING *>(read);
    return mozc::win32::ImeCore::ReconversionFromApplication(
        himc, composition_info, reading_info);
  }

  return FALSE;
}

DWORD WINAPI ImeGetImeMenuItems(HIMC himc,
                                DWORD flags,
                                DWORD type,
                                LPIMEMENUITEMINFOW ime_parent_menu,
                                LPIMEMENUITEMINFOW ime_menu,
                                DWORD size) {
  DANGLING_CALLBACK_GUARD(FALSE);
  return 0;
}

// TODO(yukawa): Refactor the implementation.
UINT WINAPI ImeToAsciiEx(UINT virtual_key,
                         UINT scan_code,
                         CONST LPBYTE key_state,
                         LPTRANSMSGLIST trans_buf,
                         UINT state,
                         HIMC himc) {
  // If fails, no message generated.
  DANGLING_CALLBACK_GUARD(0);
  if (!mozc::win32::ImeCore::IsInputContextInitialized(himc)) {
    // no message generated.
    return 0;
  }

  mozc::win32::ScopedHIMC<mozc::win32::InputContext> context(himc);
  mozc::win32::ScopedHIMCC<mozc::win32::PrivateContext>
      private_context(context->hPrivate);

  mozc::win32::VirtualKey vk =
      mozc::win32::VirtualKey::FromCombinedVirtualKey(virtual_key);
  const mozc::win32::KeyboardStatus keyboard_status(key_state);
  mozc::win32::InputState ime_state = *private_context->ime_state;
  ime_state.logical_conversion_mode = context->fdwConversion;
  ime_state.open = (context->fOpen != FALSE);
  mozc::win32::InputState next_state;
  const BYTE raw_scan_code = static_cast<BYTE>(scan_code & 0xff);
  const bool is_key_down = ((scan_code & 0x8000) == 0);
  mozc::commands::Output temporal_output;

  const mozc::win32::VKBackBasedDeleter::ClientAction vk_back_action =
      private_context->deleter->OnKeyEvent(
          vk.virtual_key(), is_key_down, false);

  // Check if this key event is handled by VKBackBasedDeleter to support
  // *deletion_range* rule.
  bool use_pending_status = false;
  bool ignore_this_keyevent = false;
  switch (vk_back_action) {
    case mozc::win32::VKBackBasedDeleter::DO_DEFAULT_ACTION:
      // do nothing.
      break;
    case mozc::win32::VKBackBasedDeleter::
             CALL_END_DELETION_THEN_DO_DEFAULT_ACTION:
      private_context->deleter->EndDeletion();
      break;
    case mozc::win32::VKBackBasedDeleter::APPLY_PENDING_STATUS:
      use_pending_status = true;
      break;
    case mozc::win32::VKBackBasedDeleter::CONSUME_KEY_BUT_NEVER_SEND_TO_SERVER:
      ignore_this_keyevent = true;
      break;
    case mozc::win32::VKBackBasedDeleter::
             CALL_END_DELETION_BUT_NEVER_SEND_TO_SERVER:
      ignore_this_keyevent = true;
      private_context->deleter->EndDeletion();
      break;
    case mozc::win32::VKBackBasedDeleter::SEND_KEY_TO_APPLICATION:
    default:
      DLOG(FATAL) << "this action is not applicable to ImeProcessKey.";
      break;
  }

  if (ignore_this_keyevent) {
    // no message generated.
    return 0;
  }

  if (context->fOpen) {
    ignore_this_keyevent = false;
    const mozc::win32::SurrogatePairObserver::ClientAction surrogate_action =
        private_context->surrogate_pair_observer->OnKeyEvent(vk, is_key_down);
    switch (surrogate_action.type) {
      case mozc::win32::SurrogatePairObserver::DO_DEFAULT_ACTION:
        break;
      case mozc::win32::SurrogatePairObserver::
             DO_DEFAULT_ACTION_WITH_RETURNED_UCS4:
        vk = mozc::win32::VirtualKey::FromUnicode(surrogate_action.ucs4);
      break;
      case mozc::win32::SurrogatePairObserver::
          CONSUME_KEY_BUT_NEVER_SEND_TO_SERVER:
        ignore_this_keyevent = true;
        break;
      default:
        DLOG(FATAL) << "this action is not applicable to ImeProcessKey.";
        break;
    }
    if (ignore_this_keyevent) {
      // no message generated.
      return 0;
    }
  }

  bool send_update_ui = false;
  bool should_be_sent_to_server = false;
  if (use_pending_status) {
    next_state = private_context->deleter->pending_ime_state();
    temporal_output.CopyFrom(
        private_context->deleter->pending_output());
    should_be_sent_to_server = true;
  } else {
    mozc::win32::InputBehavior behavior = *private_context->ime_behavior;
    mozc::commands::Context mozc_context;
    FillContext(himc, &mozc_context);

    // Update |mozc_context| with surrounding text information when available.
    {
      mozc::win32::UIContext ui_context(himc);
      if (ui_context.IsCompositionStringEmpty()) {
        mozc::win32::ImeCore::UpdateContextWithSurroundingText(himc,
                                                               &mozc_context);
      }
    }

    const mozc::win32::KeyEventHandlerResult result =
        mozc::win32::ImeCore::ImeToAsciiEx(
            private_context->client, vk, raw_scan_code, is_key_down,
            keyboard_status, behavior, ime_state, mozc_context, &next_state,
            &temporal_output);

    if (!result.succeeded) {
      // no message generated.
      return 0;
    }

    const mozc::win32::IndicatorVisibilityTracker::Action indicator_action =
        private_context->indicator_visibility_tracker->OnKey(
            vk, is_key_down, result.should_be_eaten);
    send_update_ui =
        (indicator_action ==
         mozc::win32::IndicatorVisibilityTracker::kUpdateUI);
    should_be_sent_to_server = result.should_be_sent_to_server;
  }

  mozc::win32::MessageQueue message_queue(himc);
  message_queue.Attach(trans_buf);

  if (should_be_sent_to_server) {
    mozc::win32::ImeCore::UpdateContext(
          himc, next_state, temporal_output, &message_queue);
  }

  // Generate NotifyUpdateUI message if not exists.
  {
    bool has_ui_message = false;
    const vector<TRANSMSG> &messages = message_queue.messages();
    for (size_t i = 0; i < messages.size(); ++i) {
      const TRANSMSG &msg = messages[i];
      if (msg.message == WM_IME_NOTIFY &&
          msg.wParam == IMN_PRIVATE &&
          msg.lParam == mozc::win32::kNotifyUpdateUI) {
        has_ui_message = true;
        break;
      }
    }
    if (!has_ui_message) {
      message_queue.AddMessage(
          WM_IME_NOTIFY, IMN_PRIVATE, mozc::win32::kNotifyUpdateUI);
    }
  }

  // MessageQueue::Detach returns the number of messages.
  return message_queue.Detach();
}

BOOL WINAPI ImeConfigure(HKL hkl, HWND wnd, DWORD mode, LPVOID data) {
  DANGLING_CALLBACK_GUARD(FALSE);
  if (mode == IME_CONFIG_GENERAL) {
    if (!mozc::Process::SpawnMozcProcess(
            mozc::kMozcTool, "--mode=config_dialog")) {
      return FALSE;
    }
    return TRUE;
  }

  if (mode == IME_CONFIG_SELECTDICTIONARY) {
    if (!mozc::Process::SpawnMozcProcess(
            mozc::kMozcTool, "--mode=dictionary_tool")) {
      return FALSE;
    }
    return TRUE;
  }

  if (mode == IME_CONFIG_REGISTERWORD) {
    if (data == nullptr) {
      // |data| must not be nullptr if |mode| is IME_CONFIG_REGISTERWORD.
      // http://msdn.microsoft.com/en-us/library/dd318173.aspx
      return FALSE;
    }

    // Retrieves word registration data.
    const REGISTERWORD *reg_word = static_cast<REGISTERWORD *>(data);
    const wstring word = GetStringIfWithinLimit(reg_word->lpWord,
                                                kMaxCharsForRegisterWord);
    const wstring reading = GetStringIfWithinLimit(reg_word->lpReading,
                                                   kMaxCharsForRegisterWord);

    SetEnveronmentVariablesForWordRegisterDialog(word, reading);
    const bool spawn_succeeded = mozc::Process::SpawnMozcProcess(
          mozc::kMozcTool, "--mode=word_register_dialog");
    // Delete all environment variables used.
    SetEnveronmentVariablesForWordRegisterDialog(L"", L"");

    if (!spawn_succeeded) {
      return FALSE;
    }

    return TRUE;
  }

  return FALSE;
}

BOOL WINAPI ImeRegisterWord(LPCTSTR reading, DWORD style, LPCTSTR value) {
  DANGLING_CALLBACK_GUARD(FALSE);
  return FALSE;
}

BOOL WINAPI ImeUnregisterWord(LPCTSTR lpRead, DWORD style, LPCTSTR value) {
  DANGLING_CALLBACK_GUARD(FALSE);
  return FALSE;
}

UINT WINAPI ImeGetRegisterWordStyle(UINT item, LPSTYLEBUF style_buffer) {
  DANGLING_CALLBACK_GUARD(0);
  return 0;
}

UINT WINAPI ImeEnumRegisterWord(REGISTERWORDENUMPROC enum_proc,
                                LPCTSTR reading,
                                DWORD style,
                                LPCTSTR value,
                                LPVOID data) {
  DANGLING_CALLBACK_GUARD(0);
  return 0;
}
