// 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/base/imm_util.h"

#include <windows.h>
#include <atlbase.h>
#include <atlstr.h>
#include <imm.h>
#include <msctf.h>
#include <strsafe.h>

#include <memory>
#include <string>
#include <vector>

#include "base/const.h"
#include "base/logging.h"
#include "base/scoped_handle.h"
#include "base/system_util.h"
#include "base/util.h"
#include "base/win_util.h"
#include "win32/base/imm_registrar.h"
#include "win32/base/input_dll.h"
#include "win32/base/keyboard_layout_id.h"
#include "win32/base/tsf_profile.h"

namespace mozc {
namespace win32 {
namespace {

using std::unique_ptr;

// The registry key for the CUAS setting.
// Note: We have the same values in base/win_util.cc
// TODO(yukawa): Define these constants at the same place.
const wchar_t kCUASKey[] = L"Software\\Microsoft\\CTF\\SystemShared";
const wchar_t kCUASValueName[] = L"CUAS";

// Timeout value used by a work around against b/5765783. As b/6165722
// this value is determined to be:
// - smaller than the default time-out used in IsHungAppWindow API.
// - similar to the same timeout used by TSF.
const uint32 kWaitForAsmCacheReadyEventTimeout = 4500;  // 4.5 sec.

bool GetDefaultLayout(LAYOUTORTIPPROFILE *profile) {
  if (!InputDll::EnsureInitialized()) {
    return false;
  }

  if (InputDll::enum_enabled_layout_or_tip() == nullptr) {
    return false;
  }

  const UINT num_element = InputDll::enum_enabled_layout_or_tip()(
      nullptr, nullptr, nullptr, nullptr, 0);

  unique_ptr<LAYOUTORTIPPROFILE[]> buffer(new LAYOUTORTIPPROFILE[num_element]);

  const UINT num_copied = InputDll::enum_enabled_layout_or_tip()(
      nullptr, nullptr, nullptr, buffer.get(), num_element);

  for (size_t i = 0; i < num_copied; ++i) {
    if ((buffer[i].dwFlags & LOT_DEFAULT) == LOT_DEFAULT) {
      *profile = buffer[i];
      return true;
    }
  }

  return false;
}

// The CUAS value is set to 64 bit registry keys if KEY_WOW64_64KEY is specified
// as |additional_regsam| and set to 32 bit registry keys if KEY_WOW64_32KEY is
// specified.
bool SetCuasEnabledInternal(bool enable, REGSAM additional_regsam) {
  REGSAM sam_desired = KEY_WRITE | additional_regsam;
  CRegKey key;
  LONG result = key.Open(HKEY_LOCAL_MACHINE, kCUASKey, sam_desired);
  if (ERROR_SUCCESS != result) {
    LOG(ERROR) << "Cannot open HKEY_LOCAL_MACHINE\\Software\\Microsoft\\CTF\\"
                  "SystemShared: "
               << result;
    return false;
  }
  const DWORD cuas = enable ? 1 : 0;
  result = key.SetDWORDValue(kCUASValueName, cuas);
  if (ERROR_SUCCESS != result) {
    LOG(ERROR) << "Failed to set CUAS value:" << result;
  }
  return true;
}

const wchar_t kTIPKeyboardKey[] = L"Software\\Microsoft\\CTF\\Assemblies\\"
                                  L"0x00000411\\"
                                  L"{34745C63-B2F0-4784-8B67-5E12C8701A31}";

bool IsDefaultWin8() {
  LAYOUTORTIPPROFILE profile = {};
  if (!GetDefaultLayout(&profile)) {
    return false;
  }
  // Check if this profile looks like TSF version of Mozc;
  if (profile.dwProfileType != LOTP_INPUTPROCESSOR) {
    return false;
  }
  if (!IsEqualCLSID(profile.clsid, TsfProfile::GetTextServiceGuid())) {
    return false;
  }
  if (!IsEqualGUID(profile.guidProfile, TsfProfile::GetProfileGuid())) {
    return false;
  }
  return true;
}

bool SetDefaultWin8() {
  if (!InputDll::EnsureInitialized()) {
    return false;
  }
  if (InputDll::set_default_layout_or_tip() == nullptr) {
    return false;
  }
  wchar_t clsid[64] = {};
  if (!::StringFromGUID2(TsfProfile::GetTextServiceGuid(), clsid,
                         arraysize(clsid))) {
    return E_OUTOFMEMORY;
  }
  wchar_t profile_id[64] = {};
  if (!::StringFromGUID2(TsfProfile::GetProfileGuid(), profile_id,
                         arraysize(profile_id))) {
    return E_OUTOFMEMORY;
  }

  const wstring &profile = wstring(L"0x0411:") + clsid + profile_id;
  if (!InputDll::install_layout_or_tip()(profile.c_str(), 0)) {
    DLOG(ERROR) << "InstallLayoutOrTip failed";
    return false;
  }
  if (!InputDll::set_default_layout_or_tip()(profile.c_str(), 0)) {
    DLOG(ERROR) << "SetDefaultLayoutOrTip failed";
    return false;
  }

  // Activate the TSF Mozc.
  ScopedCOMInitializer com_initializer;
  CComPtr<ITfInputProcessorProfileMgr> profile_mgr;
  if (FAILED(profile_mgr.CoCreateInstance(CLSID_TF_InputProcessorProfiles))) {
    DLOG(ERROR) << "CoCreateInstance CLSID_TF_InputProcessorProfiles failed";
    return false;
  }
  const LANGID kLANGJaJP = MAKELANGID(LANG_JAPANESE, SUBLANG_JAPANESE_JAPAN);
  if (FAILED(profile_mgr->ActivateProfile(
          TF_PROFILETYPE_INPUTPROCESSOR,
          kLANGJaJP,
          TsfProfile::GetTextServiceGuid(),
          TsfProfile::GetProfileGuid(),
          nullptr,
          TF_IPPMF_FORPROCESS | TF_IPPMF_FORSESSION))) {
    DLOG(ERROR) << "ActivateProfile failed";
    return false;
  }

  return true;
}

}  // namespace

bool ImeUtil::IsDefault() {
  if (SystemUtil::IsWindows8OrLater()) {
    return IsDefaultWin8();
  }

  LAYOUTORTIPPROFILE profile = {};
  if (GetDefaultLayout(&profile)) {
    // Check if this profile looks like IMM32 version of Mozc;
    if (profile.dwProfileType != LOTP_KEYBOARDLAYOUT) {
      return false;
    }
    if (profile.clsid != GUID_NULL) {
      return false;
    }
    if (profile.guidProfile != GUID_NULL) {
      return false;
    }

    const wstring id(profile.szId);
    // A valid |profile.szId| should consists of language ID (LANGID) and
    // keyboard layout ID (KILD) as follows.
    //  <LangID 1>:<KLID 1>
    //       "0411:E0200411"
    // Check if |id.size()| is expected.
    if (id.size() != 13) {
      return false;
    }
    // Extract KLID.  It should be 8-letter hexadecimal code begins at 6th
    // character in the |id|, that is, |id.substr(5, 8)|.
    const KeyboardLayoutID default_klid(id.substr(5, 8));
    if (!default_klid.has_id()) {
      return false;
    }
    const KeyboardLayoutID mozc_klid(ImmRegistrar::GetKLIDForIME());
    if (!mozc_klid.has_id()) {
      // This means Mozc is not installed.
      return false;
    }
    return (default_klid.id() == mozc_klid.id());
  }

  HKL hkl = nullptr;
  if (0 == ::SystemParametersInfo(SPI_GETDEFAULTINPUTLANG,
                                  0,
                                  reinterpret_cast<PVOID>(&hkl),
                                  0)) {
    LOG(ERROR) << "SystemParameterInfo failed: " << GetLastError();
    return false;
  }
  const LANGID langage_id = reinterpret_cast<LANGID>(hkl);
  const LANGID kJapaneseLangID =
      MAKELANGID(LANG_JAPANESE, SUBLANG_JAPANESE_JAPAN);

  if (langage_id != kJapaneseLangID) {
    return false;
  }

  return ImmRegistrar::IsIME(hkl, ImmRegistrar::GetFileNameForIME());
}

bool ImeUtil::SetDefault() {
  if (SystemUtil::IsWindows8OrLater()) {
    return SetDefaultWin8();
  }

  const KeyboardLayoutID &mozc_klid = win32::ImmRegistrar::GetKLIDForIME();
  if (!mozc_klid.has_id()) {
    LOG(ERROR) << "GetKLIDForIME failed: ";
    return false;
  }

  if (InputDll::EnsureInitialized() &&
      InputDll::set_default_layout_or_tip() != nullptr) {
    // In most cases, we can use this method on Vista or later.
    const wstring &profile_list = L"0x0411:0x" + mozc_klid.ToString();
    if (!InputDll::set_default_layout_or_tip()(profile_list.c_str(), 0)) {
      DLOG(ERROR) << "SetDefaultLayoutOrTip failed";
      return false;
    }
  } else {
    // We cannot use const HKL because |&mozc_hkl| will be cast into PVOID.
    HKL hkl = ::LoadKeyboardLayout(mozc_klid.ToString().c_str(), KLF_ACTIVATE);
    if (0 == ::SystemParametersInfo(SPI_SETDEFAULTINPUTLANG,
                                    0,
                                    &hkl,
                                    SPIF_SENDCHANGE)) {
      LOG(ERROR) << "SystemParameterInfo failed: " << GetLastError();
      return false;
    }

    if (S_OK != ImmRegistrar::MovePreloadValueToTop(mozc_klid)) {
      LOG(ERROR) << "MovePreloadValueToTop failed";
      return false;
    }
  }

  if (!ActivateForCurrentSession()) {
    LOG(ERROR) << "ActivateIMEForCurrentSession failed";
    return false;
  }
  return true;
}

// TF_IsCtfmonRunning looks for ctfmon.exe's mutex.
// Ctfmon.exe is running if TSF is enabled.
// Most of the implementation and comments are based on a code by
// thatanaka
bool ImeUtil::IsCtfmonRunning() {
#ifdef _M_IX86
  typedef BOOL (__stdcall *PFN_TF_ISCTFMONRUNNING)();

  // If TSF is enabled and this process has created a window, msctf.dll should
  // be loaded.
  HMODULE hMsctfDll = WinUtil::GetSystemModuleHandle(L"msctf.dll");
  if (!hMsctfDll) {
    LOG(ERROR) << "WinUtil::GetSystemModuleHandle failed";
    return false;
  }

  PFN_TF_ISCTFMONRUNNING pfnTF_IsCtfmonRunning =
      ::GetProcAddress(hMsctfDll, "TF_IsCtfmonRunning");
  if (!pfnTF_IsCtfmonRunning) {
    LOG(ERROR) << "GetProcAddress for TF_IsCtfmonRunning failed";
    return false;
  }

  return((*pfnTF_IsCtfmonRunning)() == TRUE);
#else
  // TODO(mazda): Check if the function declaration is correct.
  LOG(ERROR) << "Unsupported platform";
  return false;
#endif
}

bool ImeUtil::ActivateForCurrentProcess() {
  const KeyboardLayoutID &mozc_hkld = ImmRegistrar::GetKLIDForIME();
  if (!mozc_hkld.has_id()) {
    return false;
  }
  return (0 != ::LoadKeyboardLayout(mozc_hkld.ToString().c_str(),
                                    KLF_ACTIVATE | KLF_SETFORPROCESS));
}

bool ImeUtil::ActivateForCurrentSession() {
  const KeyboardLayoutID &mozc_hkld = ImmRegistrar::GetKLIDForIME();
  if (!mozc_hkld.has_id()) {
    return false;
  }
  const HKL mozc_hkl = ::LoadKeyboardLayout(
      mozc_hkld.ToString().c_str(), KLF_ACTIVATE);

  if (!WaitForAsmCacheReady(kWaitForAsmCacheReadyEventTimeout)) {
    LOG(ERROR) << "ImeUtil::WaitForAsmCacheReady failed.";
  }

  // Broadcasting WM_INPUTLANGCHANGEREQUEST so that existing process in the
  // current session will change their input method to |hkl|. This mechanism
  // also works against a HKL which is substituted by a TIP on Windows XP.
  // Note: we have virtually the same code in uninstall_helper.cc too.
  // TODO(yukawa): Make a common function around WM_INPUTLANGCHANGEREQUEST.
  DWORD recipients = BSM_APPLICATIONS;
  return (0 < ::BroadcastSystemMessage(
      BSF_POSTMESSAGE,
      &recipients,
      WM_INPUTLANGCHANGEREQUEST,
      INPUTLANGCHANGE_SYSCHARSET,
      reinterpret_cast<LPARAM>(mozc_hkl)));
}

// Wait for "MSCTF.AsmCacheReady.<desktop name><session #>" event signal to
// work around b/5765783.
bool ImeUtil::WaitForAsmCacheReady(uint32 timeout_msec) {
  wstring event_name;
  if (Util::UTF8ToWide(SystemUtil::GetMSCTFAsmCacheReadyEventName(),
                       &event_name) == 0) {
    LOG(ERROR) << "Failed to compose event name.";
    return false;
  }
  ScopedHandle handle(
      ::OpenEventW(SYNCHRONIZE, FALSE, event_name.c_str()));
  if (handle.get() == nullptr) {
    // Event not found.
    // Returns true assuming that we need not to wait anything.
    return true;
  }
  const DWORD result = ::WaitForSingleObject(handle.get(), timeout_msec);
  switch (result) {
    case WAIT_OBJECT_0:
      return true;
    case WAIT_TIMEOUT:
      LOG(ERROR) << "WaitForSingleObject timeout. timeout_msec: "
                 << timeout_msec;
      return false;
    case WAIT_ABANDONED:
      LOG(ERROR) << "Event was abandoned";
      return false;
    default:
      LOG(ERROR) << "WaitForSingleObject with unknown error: " << result;
      return false;
  }
  LOG(FATAL) << "Should never reach here.";
  return false;
}

}  // namespace win32
}  // namespace mozc
