// 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 "unix/ibus/mozc_engine.h"

#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <limits>
#include <map>
#include <sstream>
#include <string>

#include "base/const.h"
#include "base/file_util.h"
#include "base/logging.h"
#include "base/protobuf/descriptor.h"
#include "base/protobuf/message.h"
#include "base/singleton.h"
#include "base/system_util.h"
#include "base/util.h"
#include "client/client.h"
#include "config/config.pb.h"
#include "session/commands.pb.h"
#include "session/ime_switch_util.h"
#include "unix/ibus/engine_registrar.h"
#include "unix/ibus/ibus_candidate_window_handler.h"
#include "unix/ibus/key_event_handler.h"
#include "unix/ibus/message_translator.h"
#include "unix/ibus/mozc_engine_property.h"
#include "unix/ibus/path_util.h"
#include "unix/ibus/preedit_handler.h"
#include "unix/ibus/property_handler.h"
#include "unix/ibus/surrounding_text_util.h"

#ifdef ENABLE_GTK_RENDERER
#include "renderer/renderer_client.h"
#include "unix/ibus/gtk_candidate_window_handler.h"
#endif  // ENABLE_GTK_RENDERER

#ifdef MOZC_ENABLE_X11_SELECTION_MONITOR
#include "unix/ibus/selection_monitor.h"
#endif  // MOZC_ENABLE_X11_SELECTION_MONITOR

#ifdef ENABLE_GTK_RENDERER
DEFINE_bool(use_mozc_renderer, true,
            "The engine tries to use mozc_renderer if available.");
#endif  // ENABLE_GTK_RENDERER

namespace {

// The ID for candidates which are not associated with texts.
const int32 kBadCandidateId = -1;

#ifdef ENABLE_GTK_RENDERER
const char kMozcPanelSectionName[] = "panel";
#endif  // ENABLE_GTK_RENDERER

// Default UI locale
const char kMozcDefaultUILocale[] = "en_US.UTF-8";

// for every 5 minutes, call SyncData
const uint64 kSyncDataInterval = 5 * 60;

const char *kUILocaleEnvNames[] = {
  "LC_ALL",
  "LC_MESSAGES",
  "LANG",
};

string GetMessageLocale() {
  for (size_t i = 0; i < arraysize(kUILocaleEnvNames); ++i) {
    const char *env_ptr = ::getenv(kUILocaleEnvNames[i]);
    if (env_ptr == NULL || env_ptr[0] == '\0') {
      continue;
    }
    return env_ptr;
  }
  return kMozcDefaultUILocale;
}

bool GetString(GVariant *value, string *out_string) {
  if (g_variant_classify(value) != G_VARIANT_CLASS_STRING) {
    return false;
  }
  *out_string = static_cast<const char *>(g_variant_get_string(value, NULL));
  return true;
}

bool GetBoolean(GVariant *value, bool *out_boolean) {
  if (g_variant_classify(value) != G_VARIANT_CLASS_BOOLEAN) {
    return false;
  }
  *out_boolean = (g_variant_get_boolean(value) != FALSE);
  return true;
}

struct IBusMozcEngineClass {
  IBusEngineClass parent;
};

struct IBusMozcEngine {
  IBusEngine parent;
  mozc::ibus::MozcEngine *engine;
};

IBusEngineClass *g_parent_class = NULL;

GObject *MozcEngineClassConstructor(
    GType type,
    guint n_construct_properties,
    GObjectConstructParam *construct_properties) {
  return G_OBJECT_CLASS(g_parent_class)->constructor(type,
                                                     n_construct_properties,
                                                     construct_properties);
}

void MozcEngineClassDestroy(IBusObject *engine) {
  IBUS_OBJECT_CLASS(g_parent_class)->destroy(engine);
}

void MozcEngineClassInit(gpointer klass, gpointer class_data) {
  IBusEngineClass *engine_class = IBUS_ENGINE_CLASS(klass);

  VLOG(2) << "MozcEngineClassInit is called";
  mozc::ibus::EngineRegistrar::Register(
      mozc::Singleton<mozc::ibus::MozcEngine>::get(), engine_class);

  g_parent_class = reinterpret_cast<IBusEngineClass*>(
      g_type_class_peek_parent(klass));

  GObjectClass *object_class = G_OBJECT_CLASS(klass);
  object_class->constructor = MozcEngineClassConstructor;
  IBusObjectClass *ibus_object_class = IBUS_OBJECT_CLASS(klass);
  ibus_object_class->destroy = MozcEngineClassDestroy;
}

void MozcEngineInstanceInit(GTypeInstance *instance, gpointer klass) {
  IBusMozcEngine *engine = reinterpret_cast<IBusMozcEngine*>(instance);
  engine->engine = mozc::Singleton<mozc::ibus::MozcEngine>::get();
}

}  // namespace

namespace mozc {
namespace ibus {

namespace {
struct SurroundingTextInfo {
  SurroundingTextInfo()
      : relative_selected_length(0) {}
  int32 relative_selected_length;
  string preceding_text;
  string selection_text;
  string following_text;
};

bool GetSurroundingText(IBusEngine *engine,
#ifdef MOZC_ENABLE_X11_SELECTION_MONITOR
                        SelectionMonitorInterface *selection_monitor,
#endif  // MOZC_ENABLE_X11_SELECTION_MONITOR
                        SurroundingTextInfo *info) {
  if (!(engine->client_capabilities & IBUS_CAP_SURROUNDING_TEXT)) {
    VLOG(1) << "Give up CONVERT_REVERSE due to client_capabilities: "
            << engine->client_capabilities;
    return false;
  }
  guint cursor_pos = 0;
  guint anchor_pos = 0;
  // DO NOT call g_object_unref against this.
  // http://ibus.googlecode.com/svn/docs/ibus-1.4/IBusText.html
  // http://developer.gnome.org/gobject/stable/gobject-The-Base-Object-Type.html#gobject-The-Base-Object-Type.description
  IBusText *text = NULL;
  ibus_engine_get_surrounding_text(engine, &text, &cursor_pos,
                                   &anchor_pos);
  const string surrounding_text(ibus_text_get_text(text));

#ifdef MOZC_ENABLE_X11_SELECTION_MONITOR
  if (cursor_pos == anchor_pos && selection_monitor != NULL) {
    const SelectionInfo &info = selection_monitor->GetSelectionInfo();
    guint new_anchor_pos = 0;
    if (SurroundingTextUtil::GetAnchorPosFromSelection(
            surrounding_text, info.selected_text,
            cursor_pos, &new_anchor_pos)) {
      anchor_pos = new_anchor_pos;
    }
  }
#endif  // MOZC_ENABLE_X11_SELECTION_MONITOR

  if (!SurroundingTextUtil::GetSafeDelta(cursor_pos, anchor_pos,
                                         &info->relative_selected_length)) {
    LOG(ERROR) << "Too long text selection.";
    return false;
  }

  const size_t selection_start = min(cursor_pos, anchor_pos);
  const size_t selection_length = abs(info->relative_selected_length);
  Util::SubStringPiece(surrounding_text, 0, selection_start)
      .CopyToString(&info->preceding_text);
  Util::SubStringPiece(surrounding_text, selection_start, selection_length)
      .CopyToString(&info->selection_text);
  Util::SubStringPiece(surrounding_text, selection_start + selection_length)
      .CopyToString(&info->following_text);
  return true;
}

std::unique_ptr<client::ClientInterface> CreateAndConfigureClient() {
  std::unique_ptr<client::ClientInterface> client(
      client::ClientFactory::NewClient());
  // Currently client capability is fixed.
  commands::Capability capability;
  capability.set_text_deletion(commands::Capability::DELETE_PRECEDING_TEXT);
  client->set_client_capability(capability);
  return client;
}

}  // namespace

MozcEngine::MozcEngine()
    : last_sync_time_(Util::GetTime()),
      key_event_handler_(new KeyEventHandler),
      client_(CreateAndConfigureClient()),
#ifdef MOZC_ENABLE_X11_SELECTION_MONITOR
      selection_monitor_(SelectionMonitorFactory::Create(1024)),
#endif  // MOZC_ENABLE_X11_SELECTION_MONITOR
      property_handler_(new PropertyHandler(
          new LocaleBasedMessageTranslator(GetMessageLocale()), client_.get())),
      preedit_handler_(new PreeditHandler()),
#ifdef ENABLE_GTK_RENDERER
      gtk_candidate_window_handler_(new GtkCandidateWindowHandler(
          new renderer::RendererClient())),
#endif  // ENABLE_GTK_RENDERER
      ibus_candidate_window_handler_(new IBusCandidateWindowHandler()),
      preedit_method_(config::Config::ROMAN) {
#ifdef MOZC_ENABLE_X11_SELECTION_MONITOR
  if (selection_monitor_.get() != NULL) {
    selection_monitor_->StartMonitoring();
  }
#endif  // MOZC_ENABLE_X11_SELECTION_MONITOR

  // TODO(yusukes): write a unit test to check if the capability is set
  // as expected.
}

MozcEngine::~MozcEngine() {
  SyncData(true);
}

void MozcEngine::CandidateClicked(
    IBusEngine *engine,
    guint index,
    guint button,
    guint state) {
  if (index >= unique_candidate_ids_.size()) {
    return;
  }
  const int32 id = unique_candidate_ids_[index];
  if (id == kBadCandidateId) {
    return;
  }
  commands::Output output;
  commands::SessionCommand command;
  command.set_type(commands::SessionCommand::SELECT_CANDIDATE);
  command.set_id(id);
  client_->SendCommand(command, &output);
  UpdateAll(engine, output);
}

void MozcEngine::CursorDown(IBusEngine *engine) {
  // TODO(mazda): Implement this.
}

void MozcEngine::CursorUp(IBusEngine *engine) {
  // TODO(mazda): Implement this.
}

void MozcEngine::Disable(IBusEngine *engine) {
  RevertSession(engine);
  GetCandidateWindowHandler(engine)->Hide(engine);
  key_event_handler_->Clear();
}

void MozcEngine::Enable(IBusEngine *engine) {
  // Launch mozc_server
  client_->EnsureConnection();
  UpdatePreeditMethod();

  // When ibus-mozc is disabled by the "next input method" hot key, ibus-daemon
  // does not call MozcEngine::Disable(). Call RevertSession() here so the
  // mozc_server could discard a preedit string before the hot key is pressed
  // (crosbug.com/4596).
  RevertSession(engine);

  // If engine wants to use surrounding text, we should call
  // ibus_engine_get_surrounding_text once when the engine enabled.
  ibus_engine_get_surrounding_text(engine, NULL, NULL, NULL);
}

void MozcEngine::FocusIn(IBusEngine *engine) {
  property_handler_->Register(engine);
  UpdatePreeditMethod();
}

void MozcEngine::FocusOut(IBusEngine *engine) {
  GetCandidateWindowHandler(engine)->Hide(engine);
  property_handler_->ResetContentType(engine);

  // Note that the preedit string (if any) will be committed by IBus runtime
  // because we are specifying |IBUS_ENGINE_PREEDIT_COMMIT| flag to
  // |ibus_engine_update_preedit_text_with_mode|. All we need to do here is
  // simply resetting the current session in case there is a non-empty
  // preedit text. Note that |RevertSession| is supposed to do nothing when
  // there is no preedit text.
  // See https://code.google.com/p/mozc/issues/detail?id=255 for details.
  RevertSession(engine);
  SyncData(false);
}

void MozcEngine::PageDown(IBusEngine *engine) {
  // TODO(mazda,yusukes): Implement this to support arrow icons inside the Gtk+
  // candidate window.
}

void MozcEngine::PageUp(IBusEngine *engine) {
  // TODO(mazda,yusukes): Implement this to support arrow icons inside the Gtk+
  // candidate window.
}

gboolean MozcEngine::ProcessKeyEvent(
    IBusEngine *engine,
    guint keyval,
    guint keycode,
    guint modifiers) {
  VLOG(2) << "keyval: " << keyval
          << ", keycode: " << keycode
          << ", modifiers: " << modifiers;
  if (property_handler_->IsDisabled()) {
    return FALSE;
  }

  // Send current caret location to mozc_server to manage suggest window
  // position.
  // TODO(nona): Merge SendKey event to reduce IPC cost.
  // TODO(nona): Add a unit test against b/6209562.
  SendCaretLocation(engine->cursor_area.x,
                    engine->cursor_area.y,
                    engine->cursor_area.width,
                    engine->cursor_area.height);

  // TODO(yusukes): use |layout| in IBusEngineDesc if possible.
  const bool layout_is_jp =
      !g_strcmp0(ibus_engine_get_name(engine), "mozc-jp");

  commands::KeyEvent key;
  if (!key_event_handler_->GetKeyEvent(
          keyval, keycode, modifiers, preedit_method_, layout_is_jp, &key)) {
    // Doesn't send a key event to mozc_server.
    return FALSE;
  }

  VLOG(2) << key.DebugString();
  if (!property_handler_->IsActivated() &&
      !config::ImeSwitchUtil::IsDirectModeCommand(key)) {
    return FALSE;
  }

  key.set_activated(property_handler_->IsActivated());
  key.set_mode(property_handler_->GetOriginalCompositionMode());

  commands::Context context;
  SurroundingTextInfo surrounding_text_info;
  if (GetSurroundingText(engine,
#ifdef MOZC_ENABLE_X11_SELECTION_MONITOR
                         selection_monitor_.get(),
#endif  // MOZC_ENABLE_X11_SELECTION_MONITOR
                         &surrounding_text_info)) {
    context.set_preceding_text(surrounding_text_info.preceding_text);
    context.set_following_text(surrounding_text_info.following_text);
  }
  commands::Output output;
  if (!client_->SendKeyWithContext(key, context, &output)) {
    LOG(ERROR) << "SendKey failed";
    return FALSE;
  }

  VLOG(2) << output.DebugString();

  UpdateAll(engine, output);

  const bool consumed = output.consumed();
  return consumed ? TRUE : FALSE;
}

void MozcEngine::PropertyActivate(IBusEngine *engine,
                                  const gchar *property_name,
                                  guint property_state) {
  property_handler_->ProcessPropertyActivate(engine, property_name,
                                             property_state);
}

void MozcEngine::PropertyHide(IBusEngine *engine,
                              const gchar *property_name) {
  // We can ignore the signal.
}

void MozcEngine::PropertyShow(IBusEngine *engine,
                              const gchar *property_name) {
  // We can ignore the signal.
}

void MozcEngine::Reset(IBusEngine *engine) {
  RevertSession(engine);
}

void MozcEngine::SetCapabilities(IBusEngine *engine,
                                 guint capabilities) {
  // Do nothing.
}

void MozcEngine::SetCursorLocation(IBusEngine *engine,
                                   gint x,
                                   gint y,
                                   gint w,
                                   gint h) {
  // Do nothing
}

void MozcEngine::SetContentType(IBusEngine *engine,
                                guint purpose,
                                guint hints) {
  const bool prev_disabled =
      property_handler_->IsDisabled();
  property_handler_->UpdateContentType(engine);
  if (!prev_disabled && property_handler_->IsDisabled()) {
    // Make sure on-going composition is reverted.
    RevertSession(engine);
  }
}

GType MozcEngine::GetType() {
  static GType type = 0;

  static const GTypeInfo type_info = {
    sizeof(IBusMozcEngineClass),
    NULL,
    NULL,
    MozcEngineClassInit,
    NULL,
    NULL,
    sizeof(IBusMozcEngine),
    0,
    MozcEngineInstanceInit,
  };

  if (type == 0) {
    type = g_type_register_static(IBUS_TYPE_ENGINE,
                                  "IBusMozcEngine",
                                  &type_info,
                                  static_cast<GTypeFlags>(0));
    DCHECK_NE(type, 0) << "g_type_register_static failed";
  }

  return type;
}

// static
void MozcEngine::Disconnected(IBusBus *bus, gpointer user_data) {
  ibus_quit();
}

void MozcEngine::ConfigValueChanged(IBusConfig *config,
                                    const gchar *section,
                                    const gchar *name,
                                    GVariant *value,
                                    gpointer user_data) {
  // This function might be called _before_ MozcEngineClassInit is called if
  // you press the "Configure..." button for Mozc before switching to the Mozc
  // input method.
  MozcEngine *engine = mozc::Singleton<MozcEngine>::get();
  engine->UpdateConfig(section, name, value);
}

#ifdef ENABLE_GTK_RENDERER
void MozcEngine::InitRendererConfig(IBusConfig *config) {
  GVariant *custom_font_value = ibus_config_get_value(config,
                                                      kMozcPanelSectionName,
                                                      "custom_font");
  GVariant *use_custom_font_value = ibus_config_get_value(config,
                                                          kMozcPanelSectionName,
                                                          "use_custom_font");
  bool use_custom_font;
  if (GetBoolean(use_custom_font_value, &use_custom_font)) {
    gtk_candidate_window_handler_->OnIBusUseCustomFontDescriptionChanged(
        use_custom_font);
  } else {
    LOG(ERROR) << "Initialize Failed: "
               << "Cannot get panel:use_custom_font configuration.";
  }
  string font_description;
  if (GetString(custom_font_value, &font_description)) {
    gtk_candidate_window_handler_->OnIBusCustomFontDescriptionChanged(
       font_description);
  } else {
    LOG(ERROR) << "Initialize Failed: "
               << "Cannot get panel:custom_font configuration.";
  }
}
#endif  // ENABLE_GTK_RENDERER

// TODO(mazda): Move the impelementation to an appropriate file.
void MozcEngine::InitConfig(IBusConfig *config) {
#ifdef ENABLE_GTK_RENDERER
  MozcEngine *engine = mozc::Singleton<MozcEngine>::get();
  engine->InitRendererConfig(config);
#endif  // ENABLE_GTK_RENDERER
}

bool MozcEngine::UpdateAll(IBusEngine *engine, const commands::Output &output) {
  UpdateDeletionRange(engine, output);
  UpdateResult(engine, output);
  preedit_handler_->Update(engine, output);
  GetCandidateWindowHandler(engine)->Update(engine, output);
  UpdateCandidateIDMapping(output);

  property_handler_->Update(engine, output);

  LaunchTool(output);
  ExecuteCallback(engine, output);
  return true;
}

bool MozcEngine::UpdateDeletionRange(IBusEngine *engine,
                                     const commands::Output &output) {
  if (output.has_deletion_range() &&
      output.deletion_range().offset() < 0 &&
      output.deletion_range().offset() + output.deletion_range().length() >=
          0) {
    // Nowadays 'ibus_engine_delete_surrounding_text' becomes functional on
    // many of the major applications.  Confirmed that it works on
    // Firefox 10.0, LibreOffice 3.3.4 and GEdit 3.2.3.
    ibus_engine_delete_surrounding_text(
        engine,
        output.deletion_range().offset(), output.deletion_range().length());
  }
  return true;
}

bool MozcEngine::UpdateResult(IBusEngine *engine,
                              const commands::Output &output) const {
  if (!output.has_result()) {
    VLOG(2) << "output doesn't contain result";
    return true;
  }

  IBusText *text = ibus_text_new_from_string(output.result().value().c_str());
  ibus_engine_commit_text(engine, text);
  // |text| is released by ibus_engine_commit_text.
  return true;
}

bool MozcEngine::UpdateCandidateIDMapping(const commands::Output &output) {
  if (!output.has_candidates() || output.candidates().candidate_size() == 0) {
    return true;
  }

  unique_candidate_ids_.clear();
  const commands::Candidates &candidates = output.candidates();
  for (int i = 0; i < candidates.candidate_size(); ++i) {
    if (candidates.candidate(i).has_id()) {
      const int32 id = candidates.candidate(i).id();
      unique_candidate_ids_.push_back(id);
    } else {
      // The parent node of the cascading window does not have an id since the
      // node does not contain a candidate word.
      unique_candidate_ids_.push_back(kBadCandidateId);
    }
  }
  return true;
}

void MozcEngine::UpdateConfig(const gchar *section,
                              const gchar *name,
                              GVariant *value) {
  if (!section || !name || !value) {
    return;
  }
#ifdef ENABLE_GTK_RENDERER
  // TODO(nona): Introduce ConfigHandler
  if (g_strcmp0(section, kMozcPanelSectionName) == 0) {
    if (g_strcmp0(name, "use_custom_font") == 0) {
      bool use_custom_font;
      if (!GetBoolean(value, &use_custom_font)) {
        LOG(ERROR) << "Cannot get " << section << ":" << name << " value.";
        return;
      }
      gtk_candidate_window_handler_->OnIBusUseCustomFontDescriptionChanged(
          use_custom_font);
    } else if (g_strcmp0(name, "custom_font") == 0) {
      string font_description;
      if (!GetString(value, &font_description)) {
        LOG(ERROR) << "Cannot get " << section << ":" << name << " value.";
        return;
      }
      gtk_candidate_window_handler_->OnIBusCustomFontDescriptionChanged(
          font_description);
    }
  }
#endif  // ENABLE_GTK_RENDERER
}

void MozcEngine::UpdatePreeditMethod() {
  config::Config config;
  if (!client_->GetConfig(&config)) {
    LOG(ERROR) << "GetConfig failed";
    return;
  }
  preedit_method_ = config.has_preedit_method() ?
      config.preedit_method() : config::Config::ROMAN;
}

void MozcEngine::SyncData(bool force) {
  if (client_.get() == NULL) {
    return;
  }

  const uint64 current_time = Util::GetTime();
  if (force ||
      (current_time >= last_sync_time_ &&
       current_time - last_sync_time_ >= kSyncDataInterval)) {
    VLOG(1) << "Syncing data";
    client_->SyncData();
    last_sync_time_ = current_time;
  }
}

bool MozcEngine::LaunchTool(const commands::Output &output) const {
  if (!client_->LaunchToolWithProtoBuf(output)) {
    VLOG(2) << output.DebugString() << " Launch Failed";
    return false;
  }

  return true;
}

void MozcEngine::RevertSession(IBusEngine *engine) {
  // TODO(team): We should skip following actions when there is no on-going
  // omposition.
  commands::SessionCommand command;
  command.set_type(commands::SessionCommand::REVERT);
  commands::Output output;
  if (!client_->SendCommand(command, &output)) {
    LOG(ERROR) << "RevertSession() failed";
    return;
  }
  UpdateAll(engine, output);
}

bool MozcEngine::ExecuteCallback(IBusEngine *engine,
                                 const commands::Output &output) {
  if (!output.has_callback()) {
    return false;
  }

  // TODO(nona): Make IBus interface class and add unittest for ibus APIs.
  if (!output.callback().has_session_command()) {
    LOG(ERROR) << "callback does not have session_command";
    return false;
  }

  const commands::SessionCommand &callback_command =
      output.callback().session_command();

  if (!callback_command.has_type()) {
    LOG(ERROR) << "callback_command has no type";
    return false;
  }

  commands::SessionCommand session_command;
  session_command.set_type(callback_command.type());

  // TODO(nona): Make a function to handle CONVERT_REVERSE.
  // Used by CONVERT_REVERSE and/or UNDO
  // This value represents how many characters are selected as a relative
  // distance of characters. Positive value represents forward text selection
  // and negative value represents backword text selection.
  // Note that you should not allow 0x80000000 for |relative_selected_length|
  // because you cannot safely use |-relative_selected_length| nor
  // |abs(relative_selected_length)| in this case due to integer overflow.
  SurroundingTextInfo surrounding_text_info;

  switch (callback_command.type()) {
    case commands::SessionCommand::UNDO:
      // As far as I've tested on Ubuntu 11.10, most of applications which
      // accept 'ibus_engine_delete_surrounding_text' doe not set
      // IBUS_CAP_SURROUNDING_TEXT bit.
      // So we should carefully uncomment the following code.
      // -----
      // if (!(engine->client_capabilities & IBUS_CAP_SURROUNDING_TEXT)) {
      //   return false;
      // }
      break;
    case commands::SessionCommand::CONVERT_REVERSE: {
      if (!GetSurroundingText(engine,
#ifdef MOZC_ENABLE_X11_SELECTION_MONITOR
                              selection_monitor_.get(),
#endif  // MOZC_ENABLE_X11_SELECTION_MONITOR
                              &surrounding_text_info)) {
        return false;
      }
      session_command.set_text(surrounding_text_info.selection_text);
      break;
    }
    default:
      return false;
  }

  commands::Output new_output;
  if (!client_->SendCommand(session_command, &new_output)) {
    LOG(ERROR) << "Callback Command Failed";
    return false;
  }

  if (callback_command.type() == commands::SessionCommand::CONVERT_REVERSE) {
    // We need to remove selected text as a first step of reconversion.
    commands::DeletionRange *range = new_output.mutable_deletion_range();
    // Use DeletionRange field to remove the selected text.
    // For forward selection (that is, |relative_selected_length > 0|), the
    // offset should be a negative value to delete preceding text.
    // For backward selection (that is, |relative_selected_length < 0|),
    // IBus and/or some applications seem to expect |offset == 0| somehow.
    const int32 offset = surrounding_text_info.relative_selected_length > 0
        ? -surrounding_text_info.relative_selected_length  // forward selection
        : 0;                                               // backward selection
    range->set_offset(offset);
    range->set_length(abs(surrounding_text_info.relative_selected_length));
  }

  // Here uses recursion of UpdateAll but it's okay because the converter
  // ensures that the second output never contains callback.
  UpdateAll(engine, new_output);
  return true;
}

CandidateWindowHandlerInterface *MozcEngine::GetCandidateWindowHandler(
    IBusEngine *engine) {
#ifndef ENABLE_GTK_RENDERER
  return ibus_candidate_window_handler_.get();
#else
  if (!FLAGS_use_mozc_renderer) {
    return ibus_candidate_window_handler_.get();
  }

  if (!(engine->client_capabilities & IBUS_CAP_PREEDIT_TEXT)) {
    return ibus_candidate_window_handler_.get();
  }

  // TODO(nona): integrate with renderer/renderer_client.cc
  const string renderer_path = FileUtil::JoinPath(
      SystemUtil::GetServerDirectory(), "mozc_renderer");
  if (!FileUtil::FileExists(renderer_path)) {
    return ibus_candidate_window_handler_.get();
  }

  // TODO(nona): Check executable bit for renderer.
  return gtk_candidate_window_handler_.get();
#endif  // not ENABLE_GTK_RENDERER
}

void MozcEngine::SendCaretLocation(uint32 x, uint32 y, uint32 width,
                                   uint32 height) {
  commands::Output output;
  commands::SessionCommand command;
  command.set_type(commands::SessionCommand::SEND_CARET_LOCATION);
  commands::Rectangle *caret_rectangle = command.mutable_caret_rectangle();
  caret_rectangle->set_x(x);
  caret_rectangle->set_y(y);
  caret_rectangle->set_width(width);
  caret_rectangle->set_height(height);
  client_->SendCommand(command, &output);
}

}  // namespace ibus
}  // namespace mozc
