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

#include <sstream>
#include <vector>

#include "base/const.h"
#include "base/logging.h"
#include "base/process_mutex.h"
#include "base/scoped_handle.h"
#include "base/system_util.h"
#include "base/win_util.h"
#include "client/client.h"
#include "config/config.pb.h"
#include "config/config_handler.h"
#include "win32/base/imm_registrar.h"
#include "win32/base/imm_util.h"
#include "win32/base/migration_util.h"

DEFINE_int32(ime_switcher_target_process_id, 0,
             "The broker send messages to the process specified with this ID");
DEFINE_uint64(ime_switcher_target_process_creation_time, 0,
              "The process creation time to specify the actual process with"
              " process ID.");
DEFINE_bool(set_default_do_not_ask_again, false,
              "Set true if SetDefaultDialog should not be displayed again.");

namespace mozc {
namespace win32 {
namespace {

const char kProcessMutexPrefixForPerUserIMESettings[] =
    "mozc_hkcu_manipulation_for_ime.";

// It seems that mozc_tool basically uses the following error levels.
const int kErrorLevelProcessMutexInUse = -1;
const int kErrorLevelSuccess = 0;
const int kErrorLevelGeneralError = 1;

void NotifyFatalMessageImpl(const string &msg) {
#ifdef NO_LOGGING
  // Explicitly causes crash so that the migration failure will be notified
  // through crash dump.
  LOG(FATAL) << msg;
#else
  ::MessageBoxA(nullptr, msg.c_str(), "GoogleIMEJaBroker",
                MB_OK | MB_ICONERROR);
#endif
}

void NotifyFatalMessage(const string &msg, int line) {
  ostringstream ostr;
  ostr << msg << " (line: " << line << ")";
  NotifyFatalMessageImpl(ostr.str());
}

string GetMutexName() {
  return (kProcessMutexPrefixForPerUserIMESettings +
          SystemUtil::GetDesktopNameAsString());
}

HKL EnsureKeyboardLoaded() {
  // Check if the IMM32 version is installed.
  const KeyboardLayoutID &target_klid = ImmRegistrar::GetKLIDForIME();
  if (!target_klid.has_id()) {
    LOG(ERROR) << "KLID is not found.";
    return nullptr;
  }

  HKL hkl = ::LoadKeyboardLayoutW(
      target_klid.ToString().c_str(), KLF_ACTIVATE | KLF_SUBSTITUTE_OK);
  if (hkl == nullptr) {
    const int error = ::GetLastError();
    LOG(ERROR) << "LoadKeyboardLayoutW failed. error = " << error;
    return nullptr;
  }

  // Unload the keyboard layout once to ensure that the situation reported in
  // b/2958563 will be recovered.
  ::UnloadKeyboardLayout(hkl);

  hkl = ::LoadKeyboardLayoutW(
      target_klid.ToString().c_str(), KLF_ACTIVATE | KLF_SUBSTITUTE_OK);
  if (hkl == nullptr) {
    const int error = ::GetLastError();
    LOG(ERROR) << "LoadKeyboardLayoutW failed. error = " << error;
    return nullptr;
  }

  if (!MigrationUtil::RestorePreload()) {
    LOG(ERROR) << "RestorePreload() failed";
    return nullptr;
  }

  return hkl;
}

bool ClearCheckDefault() {
  client::Client client;
  if (!client.PingServer() && !client.EnsureConnection()) {
    LOG(ERROR) << "Cannot connect to server";
    return false;
  }
  config::Config config;
  if (!config::ConfigHandler::GetConfig(&config)) {
    LOG(ERROR) << "Cannot get config";
    return false;
  }
  config.set_check_default(false);
  if (!client.SetConfig(config)) {
    LOG(ERROR) << "Cannot set config";
    return false;
  }
  return true;
}

int RunSetDefaultWin8() {
  if (!ImeUtil::SetDefault()) {
    NotifyFatalMessage("SetDefault() failed.", __LINE__);
    return kErrorLevelGeneralError;
  }

  if (FLAGS_set_default_do_not_ask_again) {
    if (!ClearCheckDefault()) {
      // Notify the error to user but never treat this as an error.
      NotifyFatalMessage("ClearCheckDefault() failed.", __LINE__);
    }
  }
  return kErrorLevelSuccess;
}

}  // namespace

int RunSetDefault(int argc, char *argv[]) {
  if (SystemUtil::IsWindows8OrLater()) {
    return RunSetDefaultWin8();
  }

  const string mutex_name = GetMutexName();

  mozc::ProcessMutex mutex(mutex_name.c_str());
  if (!mutex.Lock()) {
    LOG(INFO) << "Another process is manipulating the IME settings.";
    return kErrorLevelProcessMutexInUse;
  }

  // Some of TSF-related utilities depend on COM runtime libraries.
  // We have to make sure that COM is initialized.
  mozc::ScopedCOMInitializer com_initializer;

  const HKL hkl = EnsureKeyboardLoaded();
  if (hkl == nullptr) {
    NotifyFatalMessage("EnsureKeyboardLoaded returns nullptr.", __LINE__);
    return kErrorLevelGeneralError;
  }

  if (!ImeUtil::SetDefault()) {
    NotifyFatalMessage("SetDefault() failed.", __LINE__);
    return kErrorLevelGeneralError;
  }

  if (FLAGS_set_default_do_not_ask_again) {
    if (!ClearCheckDefault()) {
      // Notify the error to user but never treat this as an error.
      NotifyFatalMessage("ClearCheckDefault() failed.", __LINE__);
    }
  }

  return kErrorLevelSuccess;
}
}  // namespace win32
}  // namespace mozc
