// Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chromeos_input_method.h"

#include "chromeos_input_method_ui.h"
#include "chromeos_input_method_whitelist.h"
#include "chromeos_keyboard_overlay_map.h"

#include <ibus.h>

#include <algorithm>  // for std::reverse.
#include <cstdio>
#include <cstring>  // for std::strcmp.
#include <set>
#include <sstream>
#include <stack>
#include <utility>

#include "base/singleton.h"
#include "ibus_input_methods.h"

namespace {

// Also defined in chrome/browser/chromeos/language_preferences.h (Chrome tree).
const char kGeneralSectionName[] = "general";
const char kPreloadEnginesConfigName[] = "preload_engines";

// The list of input method property keys that we don't handle.
const char* kInputMethodPropertyKeysBlacklist[] = {
  "setup",  // menu for showing setup dialog used in anthy and hangul.
  "chewing_settings_prop",  // menu for showing setup dialog used in chewing.
  "status",  // used in m17n.
};

const char* Or(const char* str1, const char* str2) {
  return str1 ? str1 : str2;
}

// Returns true if |key| is blacklisted.
bool PropertyKeyIsBlacklisted(const char* key) {
  for (size_t i = 0; i < arraysize(kInputMethodPropertyKeysBlacklist); ++i) {
    if (!std::strcmp(key, kInputMethodPropertyKeysBlacklist[i])) {
      return true;
    }
  }
  return false;
}

// Returns true if |input_method_id| is whitelisted.
// TODO(yusukes): Write unittest.
bool InputMethodIdIsWhitelisted(const char* input_method_id) {
  static std::set<std::string>* g_supported_input_methods = NULL;
  if (!g_supported_input_methods) {
    g_supported_input_methods = new std::set<std::string>;
    for (size_t i = 0; i < arraysize(kInputMethodIdsWhitelist); ++i) {
      g_supported_input_methods->insert(kInputMethodIdsWhitelist[i]);
    }
  }
  return (g_supported_input_methods->count(input_method_id) > 0);
}

// Removes input methods that are not whitelisted from |requested_input_methods|
// and stores them on |out_filtered_input_methods|.
// TODO(yusukes): Write unittest.
void FilterInputMethods(const std::vector<std::string>& requested_input_methods,
                        std::vector<std::string>* out_filtered_input_methods) {
  out_filtered_input_methods->clear();
  for (size_t i = 0; i < requested_input_methods.size(); ++i) {
    const std::string& input_method = requested_input_methods[i];
    if (InputMethodIdIsWhitelisted(input_method.c_str())) {
      out_filtered_input_methods->push_back(input_method);
    } else {
      LOG(ERROR) << "Unsupported input method: " << input_method;
    }
  }
}

// Frees input method names in |engines| and the list itself. Please make sure
// that |engines| points the head of the list.
void FreeInputMethodNames(GList* engines) {
  if (engines) {
    for (GList* cursor = engines; cursor; cursor = g_list_next(cursor)) {
      g_object_unref(IBUS_ENGINE_DESC(cursor->data));
    }
    g_list_free(engines);
  }
}

// Copies input method names in |engines| to |out|.
// TODO(yusukes): Write unittest.
void AddInputMethodNames(
    const GList* engines, chromeos::InputMethodDescriptors* out) {
  DCHECK(out);
  for (; engines; engines = g_list_next(engines)) {
    IBusEngineDesc* engine_desc = IBUS_ENGINE_DESC(engines->data);
    const gchar* name = ibus_engine_desc_get_name(engine_desc);
    const gchar* longname = ibus_engine_desc_get_longname(engine_desc);
    const gchar* layout = ibus_engine_desc_get_layout(engine_desc);
    const gchar* language = ibus_engine_desc_get_language(engine_desc);
    if (InputMethodIdIsWhitelisted(name)) {
      out->push_back(chromeos::InputMethodDescriptor(name,
                                                     longname,
                                                     layout,
                                                     language));
      DLOG(INFO) << name << " (preloaded)";
    }
  }
}

// Returns IBusInputContext for |input_context_path|. NULL on errors.
IBusInputContext* GetInputContext(
    const std::string& input_context_path, IBusBus* ibus) {
  GDBusConnection* connection = ibus_bus_get_connection(ibus);
  if (!connection) {
    LOG(ERROR) << "IBusConnection is null";
    return NULL;
  }
  // This function does not issue an IBus IPC.
  IBusInputContext* context = ibus_input_context_get_input_context(
      input_context_path.c_str(), connection);
  if (!context) {
    LOG(ERROR) << "IBusInputContext is null: " << input_context_path;
  }
  return context;
}

// Returns true if |prop| has children.
bool PropertyHasChildren(IBusProperty* prop) {
  return prop && prop->sub_props && ibus_prop_list_get(prop->sub_props, 0);
}

// This function is called by and FlattenProperty() and converts IBus
// representation of a property, |ibus_prop|, to our own and push_back the
// result to |out_prop_list|. This function returns true on success, and
// returns false if sanity checks for |ibus_prop| fail.
bool ConvertProperty(IBusProperty* ibus_prop,
                     int selection_item_id,
                     chromeos::ImePropertyList* out_prop_list) {
  DCHECK(ibus_prop);
  DCHECK(ibus_prop->key);
  DCHECK(out_prop_list);

  // Sanity checks.
  const bool has_sub_props = PropertyHasChildren(ibus_prop);
  if (has_sub_props && (ibus_prop->type != PROP_TYPE_MENU)) {
    LOG(ERROR) << "The property has sub properties, "
               << "but the type of the property is not PROP_TYPE_MENU";
    return false;
  }
  if ((!has_sub_props) && (ibus_prop->type == PROP_TYPE_MENU)) {
    // This is usually not an error. ibus-daemon sometimes sends empty props.
    DLOG(INFO) << "Property list is empty";
    return false;
  }
  if (ibus_prop->type == PROP_TYPE_SEPARATOR ||
      ibus_prop->type == PROP_TYPE_MENU) {
    // This is not an error, but we don't push an item for these types.
    return true;
  }

  const bool is_selection_item = (ibus_prop->type == PROP_TYPE_RADIO);
  selection_item_id = is_selection_item ?
      selection_item_id : chromeos::ImeProperty::kInvalidSelectionItemId;

  bool is_selection_item_checked = false;
  if (ibus_prop->state == PROP_STATE_INCONSISTENT) {
    LOG(WARNING) << "The property is in PROP_STATE_INCONSISTENT, "
                 << "which is not supported.";
  } else if ((!is_selection_item) && (ibus_prop->state == PROP_STATE_CHECKED)) {
    LOG(WARNING) << "PROP_STATE_CHECKED is meaningful only if the type is "
                 << "PROP_TYPE_RADIO.";
  } else {
    is_selection_item_checked = (ibus_prop->state == PROP_STATE_CHECKED);
  }

  if (!ibus_prop->key) {
    LOG(ERROR) << "key is NULL";
  }
  if (ibus_prop->tooltip && (!ibus_prop->tooltip->text)) {
    LOG(ERROR) << "tooltip is NOT NULL, but tooltip->text IS NULL: key="
               << Or(ibus_prop->key, "");
  }
  if (ibus_prop->label && (!ibus_prop->label->text)) {
    LOG(ERROR) << "label is NOT NULL, but label->text IS NULL: key="
               << Or(ibus_prop->key, "");
  }

  // This label will be localized on Chrome side.
  // See src/chrome/browser/chromeos/status/language_menu_l10n_util.h.
  std::string label =
      ((ibus_prop->tooltip &&
        ibus_prop->tooltip->text) ? ibus_prop->tooltip->text : "");
  if (label.empty()) {
    // Usually tooltips are more descriptive than labels.
    label = (ibus_prop->label && ibus_prop->label->text)
        ? ibus_prop->label->text : "";
  }
  if (label.empty()) {
    // ibus-pinyin has a property whose label and tooltip are empty. Fall back
    // to the key.
    label = Or(ibus_prop->key, "");
  }

  out_prop_list->push_back(chromeos::ImeProperty(ibus_prop->key,
                                                 label,
                                                 is_selection_item,
                                                 is_selection_item_checked,
                                                 selection_item_id));
  return true;
}

// Converts |ibus_prop| to |out_prop_list|. Please note that |ibus_prop|
// may or may not have children. See the comment for FlattenPropertyList
// for details. Returns true if no error is found.
// TODO(yusukes): Write unittest.
bool FlattenProperty(
    IBusProperty* ibus_prop, chromeos::ImePropertyList* out_prop_list) {
  DCHECK(ibus_prop);
  DCHECK(out_prop_list);

  int selection_item_id = -1;
  std::stack<std::pair<IBusProperty*, int> > prop_stack;
  prop_stack.push(std::make_pair(ibus_prop, selection_item_id));

  while (!prop_stack.empty()) {
    IBusProperty* prop = prop_stack.top().first;
    const int current_selection_item_id = prop_stack.top().second;
    prop_stack.pop();

    // Filter out unnecessary properties.
    if (PropertyKeyIsBlacklisted(prop->key)) {
      continue;
    }

    // Convert |prop| to ImeProperty and push it to |out_prop_list|.
    if (!ConvertProperty(prop, current_selection_item_id, out_prop_list)) {
      return false;
    }

    // Process childrens iteratively (if any). Push all sub properties to the
    // stack.
    if (PropertyHasChildren(prop)) {
      ++selection_item_id;
      for (int i = 0;; ++i) {
        IBusProperty* sub_prop = ibus_prop_list_get(prop->sub_props, i);
        if (!sub_prop) {
          break;
        }
        prop_stack.push(std::make_pair(sub_prop, selection_item_id));
      }
      ++selection_item_id;
    }
  }
  std::reverse(out_prop_list->begin(), out_prop_list->end());

  return true;
}

// Converts IBus representation of a property list, |ibus_prop_list| to our
// own. This function also flatten the original list (actually it's a tree).
// Returns true if no error is found. The conversion to our own type is
// necessary since our language switcher in Chrome tree don't (or can't) know
// IBus types. Here is an example:
//
// ======================================================================
// Input:
//
// --- Item-1
//  |- Item-2
//  |- SubMenuRoot --- Item-3-1
//  |               |- Item-3-2
//  |               |- Item-3-3
//  |- Item-4
//
// (Note: Item-3-X is a selection item since they're on a sub menu.)
//
// Output:
//
// Item-1, Item-2, Item-3-1, Item-3-2, Item-3-3, Item-4
// (Note: SubMenuRoot does not appear in the output.)
// ======================================================================
// TODO(yusukes): Write unittest.
bool FlattenPropertyList(
    IBusPropList* ibus_prop_list, chromeos::ImePropertyList* out_prop_list) {
  DCHECK(ibus_prop_list);
  DCHECK(out_prop_list);

  IBusProperty* fake_root_prop = ibus_property_new("Dummy.Key",
                                                   PROP_TYPE_MENU,
                                                   NULL, /* label */
                                                   "", /* icon */
                                                   NULL, /* tooltip */
                                                   FALSE, /* sensitive */
                                                   FALSE, /* visible */
                                                   PROP_STATE_UNCHECKED,
                                                   ibus_prop_list);
  g_return_val_if_fail(fake_root_prop, false);
  // Increase the ref count so it won't get deleted when |fake_root_prop|
  // is deleted.
  g_object_ref(ibus_prop_list);
  const bool result = FlattenProperty(fake_root_prop, out_prop_list);
  g_object_unref(fake_root_prop);

  return result;
}

// Debug print function.
const char* PropTypeToString(int prop_type) {
  switch (static_cast<IBusPropType>(prop_type)) {
    case PROP_TYPE_NORMAL:
      return "NORMAL";
    case PROP_TYPE_TOGGLE:
      return "TOGGLE";
    case PROP_TYPE_RADIO:
      return "RADIO";
    case PROP_TYPE_MENU:
      return "MENU";
    case PROP_TYPE_SEPARATOR:
      return "SEPARATOR";
  }
  return "UNKNOWN";
}

// Debug print function.
const char* PropStateToString(int prop_state) {
  switch (static_cast<IBusPropState>(prop_state)) {
    case PROP_STATE_UNCHECKED:
      return "UNCHECKED";
    case PROP_STATE_CHECKED:
      return "CHECKED";
    case PROP_STATE_INCONSISTENT:
      return "INCONSISTENT";
  }
  return "UNKNOWN";
}

// Debug print function.
std::string Spacer(int n) {
  return std::string(n, ' ');
}

std::string PrintPropList(IBusPropList *prop_list, int tree_level);
// Debug print function.
std::string PrintProp(IBusProperty *prop, int tree_level) {
  if (!prop) {
    return "";
  }

  std::stringstream stream;
  stream << Spacer(tree_level) << "=========================" << std::endl;
  stream << Spacer(tree_level) << "key: " << Or(prop->key, "<none>")
         << std::endl;
  stream << Spacer(tree_level) << "icon: " << Or(prop->icon, "<none>")
         << std::endl;
  stream << Spacer(tree_level) << "label: "
         << ((prop->label && prop->label->text) ? prop->label->text : "<none>")
         << std::endl;
  stream << Spacer(tree_level) << "tooptip: "
         << ((prop->tooltip && prop->tooltip->text)
             ? prop->tooltip->text : "<none>") << std::endl;
  stream << Spacer(tree_level) << "sensitive: "
         << (prop->sensitive ? "YES" : "NO") << std::endl;
  stream << Spacer(tree_level) << "visible: " << (prop->visible ? "YES" : "NO")
         << std::endl;
  stream << Spacer(tree_level) << "type: " << PropTypeToString(prop->type)
         << std::endl;
  stream << Spacer(tree_level) << "state: " << PropStateToString(prop->state)
         << std::endl;
  stream << Spacer(tree_level) << "sub_props: "
         << (PropertyHasChildren(prop) ? "" : "<none>") << std::endl;
  stream << PrintPropList(prop->sub_props, tree_level + 1);
  stream << Spacer(tree_level) << "=========================" << std::endl;

  return stream.str();
}

// Debug print function.
std::string PrintPropList(IBusPropList *prop_list, int tree_level) {
  if (!prop_list) {
    return "";
  }

  std::stringstream stream;
  for (int i = 0;; ++i) {
    IBusProperty* prop = ibus_prop_list_get(prop_list, i);
    if (!prop) {
      break;
    }
    stream << PrintProp(prop, tree_level);
  }
  return stream.str();
}

}  // namespace

namespace chromeos {

// A singleton class that holds IBus connections.
class InputMethodStatusConnection {
 public:
  // Returns a singleton object of the class. If the singleton object is already
  // initialized, the arguments are ignored.
  // Warning: you can call the callback functions only in the ibus callback
  // functions like FocusIn(). See http://crosbug.com/5217#c9 for details.
  static InputMethodStatusConnection* GetConnection(
      void* language_library,
      LanguageCurrentInputMethodMonitorFunction current_input_method_changed,
      LanguageRegisterImePropertiesFunction register_ime_properties,
      LanguageUpdateImePropertyFunction update_ime_property,
      LanguageConnectionChangeMonitorFunction connection_change_handler) {
    DCHECK(language_library);
    DCHECK(current_input_method_changed),
    DCHECK(register_ime_properties);
    DCHECK(update_ime_property);

    InputMethodStatusConnection* object = Singleton<InputMethodStatusConnection,
        LeakySingletonTraits<InputMethodStatusConnection> >::get();
    if (!object->language_library_) {
      object->language_library_ = language_library;
      object->current_input_method_changed_ = current_input_method_changed;
      object->register_ime_properties_= register_ime_properties;
      object->update_ime_property_ = update_ime_property;
      object->connection_change_handler_ = connection_change_handler;
      object->MaybeRestoreConnections();
    } else if (object->language_library_ != language_library) {
      LOG(ERROR) << "Unknown language_library is passed";
    }
    return object;
  }

  // Called by cros API ChromeOSStopInputMethodProcess().
  bool StopInputMethodProcess() {
    if (!IBusConnectionsAreAlive()) {
      LOG(ERROR) << "StopInputMethodProcess: IBus connection is not alive";
      return false;
    }

    // Ask IBus to exit *asynchronously*.
    ibus_bus_exit_async(ibus_,
                        FALSE  /* do not restart */,
                        -1  /* timeout */,
                        NULL  /* cancellable */,
                        NULL  /* callback */,
                        NULL  /* user_data */);

    if (ibus_config_) {
      // Release |ibus_config_| unconditionally to make sure next
      // IBusConnectionsAreAlive() call will return false.
      g_object_unref(ibus_config_);
      ibus_config_ = NULL;
    }
    return true;
  }

  // Called by cros API ChromeOS(Activate|Deactive)ImeProperty().
  void SetImePropertyActivated(const char* key, bool activated) {
    if (!IBusConnectionsAreAlive()) {
      LOG(ERROR) << "SetImePropertyActivated: IBus connection is not alive";
      return;
    }
    if (!key || (key[0] == '\0')) {
      return;
    }
    if (input_context_path_.empty()) {
      LOG(ERROR) << "Input context is unknown";
      return;
    }

    IBusInputContext* context = GetInputContext(input_context_path_, ibus_);
    if (!context) {
      return;
    }
    // Activate the property *asynchronously*.
    ibus_input_context_property_activate(
        context, key, (activated ? PROP_STATE_CHECKED : PROP_STATE_UNCHECKED));

    // We don't have to call ibus_proxy_destroy(context) explicitly here,
    // i.e. we can just call g_object_unref(context), since g_object_unref can
    // trigger both dispose, which is overridden by src/ibusproxy.c, and
    // finalize functions. For details, see
    // http://library.gnome.org/devel/gobject/stable/gobject-memory.html
    g_object_unref(context);
  }

  // Called by cros API ChromeOSChangeInputMethod().
  bool ChangeInputMethod(const char* name) {
    if (!IBusConnectionsAreAlive()) {
      LOG(ERROR) << "ChangeInputMethod: IBus connection is not alive";
      return false;
    }
    if (!name) {
      return false;
    }
    if (!InputMethodIdIsWhitelisted(name)) {
      LOG(ERROR) << "Input method '" << name << "' is not supported";
      return false;
    }

    // Clear all input method properties unconditionally.
    //
    // When switching to another input method and no text area is focused,
    // RegisterProperties signal for the new input method will NOT be sent
    // until a text area is focused. Therefore, we have to clear the old input
    // method properties here to keep the input method switcher status
    // consistent.
    RegisterProperties(NULL);

    // Change the global engine *asynchronously*.
    ibus_bus_set_global_engine_async(ibus_,
                                     name,
                                     -1,  // use the default ibus timeout
                                     NULL,  // cancellable
                                     NULL,  // callback
                                     NULL);  // user_data
    return true;
  }

  // Updates a configuration of ibus-daemon or IBus engines with |value|.
  // Returns true if the configuration is successfully updated.
  //
  // For more information, please read a comment for SetImeConfig() function
  // in chromeos_language.h.
  bool SetImeConfig(const std::string& section,
                    const std::string& config_name,
                    const ImeConfigValue& value) {
    // See comments in GetImeConfig() where ibus_config_get_value() is used.
    if (!IBusConnectionsAreAlive()) {
      LOG(ERROR) << "SetImeConfig: IBus connection is not alive";
      return false;
    }

    bool is_preload_engines = false;

    // Sanity check: do not preload unknown/unsupported input methods.
    std::vector<std::string> string_list;
    if ((value.type == ImeConfigValue::kValueTypeStringList) &&
        (section == kGeneralSectionName) &&
        (config_name == kPreloadEnginesConfigName)) {
      FilterInputMethods(value.string_list_value, &string_list);
      is_preload_engines = true;
    } else {
      string_list = value.string_list_value;
    }

    // Convert the type of |value| from our structure to GVariant.
    GVariant* variant = NULL;
    switch (value.type) {
      case ImeConfigValue::kValueTypeString:
        variant = g_variant_new_string(value.string_value.c_str());
        break;
      case ImeConfigValue::kValueTypeInt:
        variant = g_variant_new_int32(value.int_value);
        break;
      case ImeConfigValue::kValueTypeBool:
        variant = g_variant_new_boolean(value.bool_value);
        break;
      case ImeConfigValue::kValueTypeStringList:
        GVariantBuilder variant_builder;
        g_variant_builder_init(&variant_builder, G_VARIANT_TYPE("as"));
        const size_t size = string_list.size();  // don't use string_list_value.
        for (size_t i = 0; i < size; ++i) {
          g_variant_builder_add(&variant_builder, "s", string_list[i].c_str());
        }
        variant = g_variant_builder_end(&variant_builder);
        break;
    }

    if (!variant) {
      LOG(ERROR) << "SetImeConfig: variant is NULL";
      return false;
    }
    DCHECK(g_variant_is_floating(variant));

    // Set an ibus configuration value *asynchronously*.
    ibus_config_set_value_async(ibus_config_,
                                section.c_str(),
                                config_name.c_str(),
                                variant,
                                -1,  // use the default ibus timeout
                                NULL,  // cancellable
                                SetImeConfigCallback,
                                g_object_ref(ibus_config_));

    // Since |variant| is floating, ibus_config_set_value_async consumes
    // (takes ownership of) the variable.

    if (is_preload_engines) {
      DLOG(INFO) << "SetImeConfig: " << section << "/" << config_name
                 << ": " << value.ToString();
    }
    return true;
  }

 private:
  friend struct DefaultSingletonTraits<InputMethodStatusConnection>;
  InputMethodStatusConnection()
      : current_input_method_changed_(NULL),
        register_ime_properties_(NULL),
        update_ime_property_(NULL),
        connection_change_handler_(NULL),
        language_library_(NULL),
        ibus_(NULL),
        ibus_config_(NULL) {
  }

  ~InputMethodStatusConnection() {
    // Since the class is used as a leaky singleton, this destructor is never
    // called. However, if you would delete an instance of this class, you have
    // to disconnect all signals so the handler functions will not be called
    // with |this| which is already freed.
    //
    // if (ibus_) {
    //   g_signal_handlers_disconnect_by_func(
    //       ibus_,
    //       reinterpret_cast<gpointer>(
    //           G_CALLBACK(IBusBusConnectedCallback)),
    //       this);
    //   ...
    // }
    // if (ibus_panel_service_) {
    //   g_signal_handlers_disconnect_by_func(
    //       ...
  }

  // Checks if |ibus_| and |ibus_config_| connections are alive.
  bool IBusConnectionsAreAlive() {
    return ibus_ && ibus_bus_is_connected(ibus_) && ibus_config_;
  }

  // Restores connections to ibus-daemon and ibus-memconf if they are not ready.
  // If both |ibus_| and |ibus_config_| become ready, the function sends a
  // notification to Chrome.
  void MaybeRestoreConnections() {
    if (IBusConnectionsAreAlive()) {
      return;
    }
    MaybeCreateIBus();
    MaybeRestoreIBusConfig();
    if (IBusConnectionsAreAlive()) {
      ConnectPanelServiceSignals();
      if (connection_change_handler_) {
        LOG(INFO) << "Notifying Chrome that IBus is ready.";
        connection_change_handler_(language_library_, true);
      }
    }
  }

  // Creates IBusBus object if it's not created yet.
  void MaybeCreateIBus() {
    if (ibus_) {
      return;
    }

    ibus_init();
    // Establish IBus connection between ibus-daemon to retrieve the list of
    // available input method engines, change the current input method engine,
    // and so on.
    ibus_ = ibus_bus_new();

    // Check the IBus connection status.
    if (!ibus_) {
      LOG(ERROR) << "ibus_bus_new() failed";
      return;
    }
    // Register callback functions for IBusBus signals.
    ConnectIBusSignals();

    // Ask libibus to watch the NameOwnerChanged signal *asynchronously*.
    ibus_bus_set_watch_dbus_signal(ibus_, TRUE);
    // Ask libibus to watch the GlobalEngineChanged signal *asynchronously*.
    ibus_bus_set_watch_ibus_signal(ibus_, TRUE);

    if (ibus_bus_is_connected(ibus_)) {
      LOG(INFO) << "ibus_bus_is_connected(). IBus connection is ready!";
    }
  }

  // Creates IBusConfig object if it's not created yet AND |ibus_| connection
  // is ready.
  void MaybeRestoreIBusConfig() {
    if (!ibus_) {
      return;
    }

    // Destroy the current |ibus_config_| object. No-op if it's NULL.
    MaybeDestroyIBusConfig();

    if (!ibus_config_) {
      GDBusConnection* ibus_connection = ibus_bus_get_connection(ibus_);
      if (!ibus_connection) {
        LOG(ERROR) << "ibus_bus_get_connection() failed. ibus-daemon is "
                   << "restarted and |ibus_| connection is not recovered yet?";
        return;
      }
      const gboolean disconnected
          = g_dbus_connection_is_closed(ibus_connection);
      if (disconnected) {
        // |ibus_| object is not NULL, but the connection between ibus-daemon
        // is not yet established. In this case, we don't create |ibus_config_|
        // object.
        LOG(WARNING) << "Couldn't create an ibus config object since "
                     << "ibus_connection_is_connected() returned false.";
        return;
      }
      // If memconf is not successfully started yet, ibus_config_new() will
      // return NULL. Otherwise, it returns a transfer-none and non-floating
      // object. ibus_config_new() sometimes issues a D-Bus *synchronous* IPC
      // to check if the org.freedesktop.IBus.Config service is available.
      ibus_config_ = ibus_config_new(ibus_connection,
                                     NULL /* do not cancel the operation */,
                                     NULL /* do not get error information */);
      if (!ibus_config_) {
        LOG(ERROR) << "ibus_config_new() failed. ibus-memconf is not ready?";
        return;
      }

      // TODO(yusukes): g_object_weak_ref might be better since it allows
      // libcros to detect the delivery of the "destroy" glib signal the
      // |ibus_config_| object.
      g_object_ref(ibus_config_);
      LOG(INFO) << "ibus_config_ is ready!";
    }
  }

  // Destroys IBusConfig object if |ibus_| connection is not ready. This
  // function does nothing if |ibus_config_| is NULL or |ibus_| connection is
  // still alive. Note that the IBusConfig object can't be used when |ibus_|
  // connection is not ready.
  void MaybeDestroyIBusConfig() {
    if (!ibus_) {
      LOG(ERROR) << "MaybeDestroyIBusConfig: ibus_ is NULL";
      return;
    }
    if (ibus_config_ && !ibus_bus_is_connected(ibus_)) {
      g_object_unref(ibus_config_);
      ibus_config_ = NULL;
    }
  }

  // Handles "FocusIn" signal from chromeos_input_method_ui.
  void FocusIn(const char* input_context_path) {
    if (!input_context_path) {
      LOG(ERROR) << "NULL context passed";
    } else {
      DLOG(INFO) << "FocusIn: " << input_context_path;
    }
    // Remember the current ic path.
    input_context_path_ = Or(input_context_path, "");
  }

  // Handles "RegisterProperties" signal from chromeos_input_method_ui.
  void RegisterProperties(IBusPropList* ibus_prop_list) {
    DLOG(INFO) << "RegisterProperties" << (ibus_prop_list ? "" : " (clear)");

    ImePropertyList prop_list;  // our representation.
    if (ibus_prop_list) {
      // You can call
      //   LOG(INFO) << "\n" << PrintPropList(ibus_prop_list, 0);
      // here to dump |ibus_prop_list|.
      if (!FlattenPropertyList(ibus_prop_list, &prop_list)) {
        // Clear properties on errors.
        RegisterProperties(NULL);
        return;
      }
    }
    // Notify the change.
    register_ime_properties_(language_library_, prop_list);
  }

  // Handles "UpdateProperty" signal from chromeos_input_method_ui.
  void UpdateProperty(IBusProperty* ibus_prop) {
    DLOG(INFO) << "UpdateProperty";
    DCHECK(ibus_prop);

    // You can call
    //   LOG(INFO) << "\n" << PrintProp(ibus_prop, 0);
    // here to dump |ibus_prop|.

    ImePropertyList prop_list;  // our representation.
    if (!FlattenProperty(ibus_prop, &prop_list)) {
      // Don't update the UI on errors.
      LOG(ERROR) << "Malformed properties are detected";
      return;
    }
    // Notify the change.
    if (!prop_list.empty()) {
      update_ime_property_(language_library_, prop_list);
    }
  }

  // Retrieves input method status and notifies them to the UI.
  // |current_global_engine_id| is the current global engine id such as "mozc"
  // and "xkb:us::eng". If the id is unknown, an empty string "" can be passed.
  // Warning: you can call this function only from ibus callback functions
  // like FocusIn(). See http://crosbug.com/5217#c9 for details.
  void UpdateUI(const char* current_global_engine_id) {
    DCHECK(current_global_engine_id);

    const chromeos::IBusEngineInfo* engine_info = NULL;
    for (size_t i = 0; i < arraysize(chromeos::ibus_engines); ++i) {
      if (chromeos::ibus_engines[i].name ==
          std::string(current_global_engine_id)) {
        engine_info = &chromeos::ibus_engines[i];
        break;
      }
    }

    if (!engine_info) {
      LOG(ERROR) << current_global_engine_id
                 << " is not found in the input method white-list.";
      return;
    }

    InputMethodDescriptor current_input_method(engine_info->name,
                                               engine_info->longname,
                                               engine_info->layout,
                                               engine_info->language);

    DLOG(INFO) << "Updating the UI. ID:" << current_input_method.id
               << ", keyboard_layout:" << current_input_method.keyboard_layout;

    // Notify the change to update UI.
    current_input_method_changed_(language_library_, current_input_method);
  }

  // Installs gobject signal handlers to |ibus_|.
  void ConnectIBusSignals() {
    if (!ibus_) {
      return;
    }

    // We use g_signal_connect_after here since the callback should be called
    // *after* the IBusBusDisconnectedCallback in chromeos_input_method_ui.cc
    // is called. chromeos_input_method_ui.cc attaches the panel service object
    // to |ibus_|, and the callback in this file use the attached object.
    g_signal_connect_after(ibus_,
                           "connected",
                           G_CALLBACK(IBusBusConnectedCallback),
                           this);

    g_signal_connect(ibus_,
                     "disconnected",
                     G_CALLBACK(IBusBusDisconnectedCallback),
                     this);
    g_signal_connect(ibus_,
                     "global-engine-changed",
                     G_CALLBACK(IBusBusGlobalEngineChangedCallback),
                     this);
    g_signal_connect(ibus_,
                     "name-owner-changed",
                     G_CALLBACK(IBusBusNameOwnerChangedCallback),
                     this);
  }

  // Installs gobject signal handlers to the panel service.
  void ConnectPanelServiceSignals() {
    if (!ibus_) {
      return;
    }

    IBusPanelService* ibus_panel_service = IBUS_PANEL_SERVICE(
        g_object_get_data(G_OBJECT(ibus_), kPanelObjectKey));
    if (!ibus_panel_service) {
      LOG(ERROR) << "IBusPanelService is NOT available.";
      return;
    }
    // We don't _ref() or _weak_ref() the panel service object, since we're not
    // interested in the life time of the object.

    g_signal_connect(ibus_panel_service,
                     "focus-in",
                     G_CALLBACK(FocusInCallback),
                     this);
    g_signal_connect(ibus_panel_service,
                     "register-properties",
                     G_CALLBACK(RegisterPropertiesCallback),
                     this);
    g_signal_connect(ibus_panel_service,
                     "update-property",
                     G_CALLBACK(UpdatePropertyCallback),
                     this);
  }

  // Handles "connected" signal from ibus-daemon.
  static void IBusBusConnectedCallback(IBusBus* bus, gpointer user_data) {
    LOG(WARNING) << "IBus connection is recovered.";
    // ibus-daemon might be restarted, or the daemon was not running when Chrome
    // started. Anyway, since |ibus_| connection is now ready, it's possible to
    // create |ibus_config_| object by calling MaybeRestoreConnections().
    g_return_if_fail(user_data);
    InputMethodStatusConnection* self
        = static_cast<InputMethodStatusConnection*>(user_data);
    self->MaybeRestoreConnections();
  }

  // Handles "disconnected" signal from ibus-daemon.
  static void IBusBusDisconnectedCallback(IBusBus* bus, gpointer user_data) {
    LOG(WARNING) << "IBus connection is terminated!";
    g_return_if_fail(user_data);
    InputMethodStatusConnection* self
        = static_cast<InputMethodStatusConnection*>(user_data);
    // ibus-daemon might be terminated. Since |ibus_| object will automatically
    // connect to the daemon if it restarts, we don't have to set NULL on ibus_.
    // Call MaybeDestroyIBusConfig() to set |ibus_config_| to NULL temporarily.
    self->MaybeDestroyIBusConfig();
    if (self->connection_change_handler_) {
      LOG(INFO) << "Notifying Chrome that IBus is terminated.";
      self->connection_change_handler_(self->language_library_, false);
    }
  }

  // Handles "global-engine-changed" signal from ibus-daemon.
  static void IBusBusGlobalEngineChangedCallback(
      IBusBus* bus, const gchar* engine_name, gpointer user_data) {
    DCHECK(engine_name);
    DLOG(INFO) << "Global engine is changed to " << engine_name;
    g_return_if_fail(user_data);
    InputMethodStatusConnection* self
        = static_cast<InputMethodStatusConnection*>(user_data);
    self->UpdateUI(engine_name);
  }

  // Handles "name-owner-changed" signal from ibus-daemon. The signal is sent
  // to libcros when an IBus component such as ibus-memconf, ibus-engine-*, ..
  // is started.
  static void IBusBusNameOwnerChangedCallback(
      IBusBus* bus,
      const gchar* name, const gchar* old_name, const gchar* new_name,
      gpointer user_data) {
    DCHECK(name);
    DCHECK(old_name);
    DCHECK(new_name);
    DLOG(INFO) << "Name owner is changed: name=" << name
               << ", old_name=" << old_name << ", new_name=" << new_name;

    if (name != std::string("org.freedesktop.IBus.Config")) {
      // Not a signal for ibus-memconf.
      return;
    }

    const std::string empty_string;
    if (old_name != empty_string || new_name == empty_string) {
      // ibus-memconf died?
      LOG(WARNING) << "Unexpected name owner change: name=" << name
                   << ", old_name=" << old_name << ", new_name=" << new_name;
      // TODO(yusukes): it might be nice to set |ibus_config_| to NULL and call
      // |connection_change_handler_| with false here to allow Chrome to
      // recover all input method configurations when ibus-memconf is
      // automatically restarted by ibus-daemon. Though ibus-memconf is pretty
      // stable and unlikely crashes.
      return;
    }

    LOG(INFO) << "IBus config daemon is started. Recovering ibus_config_";
    g_return_if_fail(user_data);
    InputMethodStatusConnection* self
        = static_cast<InputMethodStatusConnection*>(user_data);

    // Try to recover |ibus_config_|. If the |ibus_config_| object is
    // successfully created, |connection_change_handler_| will be called to
    // notify Chrome that IBus is ready.
    self->MaybeRestoreConnections();
  }

  // Handles "FocusIn" signal from chromeos_input_method_ui.
  static void FocusInCallback(IBusPanelService* panel,
                              const gchar* path,
                              gpointer user_data) {
    g_return_if_fail(user_data);
    InputMethodStatusConnection* self
        = static_cast<InputMethodStatusConnection*>(user_data);
    self->FocusIn(path);
  }

  // Handles "RegisterProperties" signal from chromeos_input_method_ui.
  static void RegisterPropertiesCallback(IBusPanelService* panel,
                                         IBusPropList* prop_list,
                                         gpointer user_data) {
    g_return_if_fail(user_data);
    InputMethodStatusConnection* self
        = static_cast<InputMethodStatusConnection*>(user_data);
    self->RegisterProperties(prop_list);
  }

  // Handles "UpdateProperty" signal from chromeos_input_method_ui.
  static void UpdatePropertyCallback(IBusPanelService* panel,
                                     IBusProperty* ibus_prop,
                                     gpointer user_data) {
    g_return_if_fail(user_data);
    InputMethodStatusConnection* self
        = static_cast<InputMethodStatusConnection*>(user_data);
    self->UpdateProperty(ibus_prop);
  }

  // A callback function that will be called when ibus_config_set_value_async()
  // request is finished.
  static void SetImeConfigCallback(GObject* source_object,
                                   GAsyncResult* res,
                                   gpointer user_data) {
    IBusConfig* config = IBUS_CONFIG(user_data);
    g_return_if_fail(config);

    GError* error = NULL;
    const gboolean result =
        ibus_config_set_value_async_finish(config, res, &error);

    if (!result) {
      std::string message = "(unknown error)";
      if (error && error->message) {
        message = error->message;
      }
      LOG(ERROR) << "ibus_config_set_value_async failed: " << message;
    }

    if (error) {
      g_error_free(error);
    }
    g_object_unref(config);
  }

  // A function pointers which point LanguageLibrary::XXXHandler functions.
  // The functions are used when libcros receives signals from ibus-daemon.
  LanguageCurrentInputMethodMonitorFunction current_input_method_changed_;
  LanguageRegisterImePropertiesFunction register_ime_properties_;
  LanguageUpdateImePropertyFunction update_ime_property_;
  LanguageConnectionChangeMonitorFunction connection_change_handler_;

  // Points to a chromeos::LanguageLibrary object. |language_library_| is used
  // as the first argument of the monitor functions above.
  void* language_library_;

  // Connection to the ibus-daemon via IBus API. These objects are used to
  // call ibus-daemon's API (e.g. activate input methods, set config, ...)
  IBusBus* ibus_;
  IBusConfig* ibus_config_;

  // Current input context path.
  std::string input_context_path_;
};

//
// cros APIs
//

// The function will be bound to chromeos::MonitorInputMethodStatus with dlsym()
// in load.cc so it needs to be in the C linkage, so the symbol name does not
// get mangled.
extern "C"
InputMethodStatusConnection* ChromeOSMonitorInputMethodStatus(
    void* language_library,
    LanguageCurrentInputMethodMonitorFunction current_input_method_changed,
    LanguageRegisterImePropertiesFunction register_ime_properties,
    LanguageUpdateImePropertyFunction update_ime_property,
    LanguageConnectionChangeMonitorFunction connection_changed) {
  DLOG(INFO) << "MonitorInputMethodStatus";
  return InputMethodStatusConnection::GetConnection(
      language_library,
      current_input_method_changed,
      register_ime_properties,
      update_ime_property,
      connection_changed);
}

extern "C"
bool ChromeOSStopInputMethodProcess(InputMethodStatusConnection* connection) {
  g_return_val_if_fail(connection, false);
  return connection->StopInputMethodProcess();
}

extern "C"
InputMethodDescriptors* ChromeOSGetSupportedInputMethodDescriptors() {
  InputMethodDescriptors* input_methods = new InputMethodDescriptors;
  for (size_t i = 0; i < arraysize(chromeos::ibus_engines); ++i) {
    if (InputMethodIdIsWhitelisted(chromeos::ibus_engines[i].name)) {
      input_methods->push_back(chromeos::InputMethodDescriptor(
          chromeos::ibus_engines[i].name,
          chromeos::ibus_engines[i].longname,
          chromeos::ibus_engines[i].layout,
          chromeos::ibus_engines[i].language));
    }
  }
  return input_methods;
}

extern "C"
void ChromeOSSetImePropertyActivated(
    InputMethodStatusConnection* connection, const char* key, bool activated) {
  DLOG(INFO) << "SetImePropertyeActivated: " << key << ": " << activated;
  DCHECK(key);
  g_return_if_fail(connection);
  connection->SetImePropertyActivated(key, activated);
}

extern "C"
bool ChromeOSChangeInputMethod(
    InputMethodStatusConnection* connection, const char* name) {
  DCHECK(name);
  DLOG(INFO) << "ChangeInputMethod: " << name;
  g_return_val_if_fail(connection, false);
  return connection->ChangeInputMethod(name);
}

extern "C"
bool ChromeOSSetImeConfig(InputMethodStatusConnection* connection,
                          const char* section,
                          const char* config_name,
                          const ImeConfigValue& value) {
  DCHECK(section);
  DCHECK(config_name);
  g_return_val_if_fail(connection, FALSE);
  return connection->SetImeConfig(section, config_name, value);
}

extern "C"
std::string ChromeOSGetKeyboardOverlayId(const std::string& input_method_id) {
  for (size_t i = 0; i < arraysize(kKeyboardOverlayMap); ++i) {
    if (kKeyboardOverlayMap[i].input_method_id == input_method_id) {
      return kKeyboardOverlayMap[i].keyboard_overlay_id;
    }
  }
  return "";
}

}  // namespace chromeos
