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

#include <base/logging.h>
#include <base/string_util.h>
#include <base/utf_string_conversions.h>
#include <ibus.h>

namespace chromeos {

namespace {

// Checks the attribute if this indicates annotation.
gboolean IsAnnotation(IBusAttribute *attr) {
  g_return_val_if_fail(attr, FALSE);

  // Define annotation text color.
  static const guint kAnnotationColor = 0x888888;

  // Currently, we can discriminate annotation by specific value |attr->value|
  // TODO(nhiroki): We should change the way when iBus supports annotations.
  if (attr->type == IBUS_ATTR_TYPE_FOREGROUND &&
      attr->value == kAnnotationColor) {
    return TRUE;
  }
  return FALSE;
}

// Returns an string representation of |table| for debugging.
std::string IBusLookupTableToString(IBusLookupTable* table) {
  std::stringstream stream;
  stream << "page_size: " << table->page_size << "\n";
  stream << "cursor_pos: " << table->cursor_pos << "\n";
  stream << "cursor_visible: " << table->cursor_visible << "\n";
  stream << "round: " << table->round << "\n";
  stream << "orientation: " << table->orientation << "\n";
  stream << "candidates:";
  for (int i = 0; ; i++) {
    IBusText *text = ibus_lookup_table_get_candidate(table, i);
    if (!text) {
      break;
    }
    stream << " " << text->text;
  }
  return stream.str();
}

}  // namespace

// A thin wrapper for IBusPanelService.
class InputMethodUiStatusConnection {
 public:
  InputMethodUiStatusConnection(
      const InputMethodUiStatusMonitorFunctions& monitor_functions,
      void* input_method_library)
      : monitor_functions_(monitor_functions),
        connection_change_handler_(NULL),
        input_method_library_(input_method_library),
        ibus_(NULL),
        ibus_panel_service_(NULL) {
  }

  ~InputMethodUiStatusConnection() {
    // ibus_panel_service_ depends on ibus_, thus unref it first.
    if (ibus_panel_service_) {
      DisconnectPanelServiceSignals();
      g_object_unref(ibus_panel_service_);
    }
    if (ibus_) {
      DisconnectIBusSignals();
      g_object_unref(ibus_);
    }
  }

  // Creates IBusBus object if it's not created yet, and tries to connect to
  // ibus-daemon. Returns true if IBusBus is successfully connected to the
  // daemon.
  bool ConnectToIBus() {
    if (ibus_) {
      return true;
    }
    ibus_init();
    ibus_ = ibus_bus_new();
    CHECK(ibus_) << "ibus_bus_new() failed. Out of memory?";

    bool result = false;
    // Check the IBus connection status.
    if (ibus_bus_is_connected(ibus_)) {
      LOG(INFO) << "ibus_bus_is_connected(). IBus connection is ready!";
      if (connection_change_handler_) {
        connection_change_handler_(input_method_library_, true);
      }
      result = true;
    }

    // Start listening the gobject signals regardless of the bus connection
    // status.
    ConnectIBusSignals();
    return result;
  }

  // Creates IBusPanelService object if |ibus_| is already connected.
  bool MaybeRestorePanelService() {
    if (!ibus_ || !ibus_bus_is_connected(ibus_)) {
      return false;
    }

    if (ibus_panel_service_) {
      LOG(ERROR) << "IBusPanelService is already available. Remove it first.";
      g_object_set_data(G_OBJECT(ibus_), kPanelObjectKey, NULL);
      g_object_unref(ibus_panel_service_);
      ibus_panel_service_ = NULL;
    }

    // Create an IBusPanelService object.
    GDBusConnection* ibus_connection = ibus_bus_get_connection(ibus_);
    if (!ibus_connection) {
      LOG(ERROR) << "ibus_bus_get_connection() failed";
      return false;
    }
    ibus_panel_service_ = ibus_panel_service_new(ibus_connection);
    if (!ibus_panel_service_) {
      LOG(ERROR) << "ibus_chromeos_panel_service_new() failed";
      return false;
    }
    ConnectPanelServiceSignals();
    g_object_set_data(G_OBJECT(ibus_), kPanelObjectKey, ibus_panel_service_);
    LOG(INFO) << "IBusPanelService object is successfully (re-)created.";

    // Request the well-known name *synchronously*.
    const int status = ibus_bus_request_name(ibus_, IBUS_SERVICE_PANEL, 0);
    if (status == 0) {
      LOG(ERROR) << "ibus_bus_request_name() failed";
      return false;
    }
    return true;
  }

  // A function called when a user clicks the candidate_window.
  bool NotifyCandidateClicked(int index, int button, int flags) {
    if (!ibus_ || !ibus_bus_is_connected(ibus_)) {
      LOG(ERROR) << "NotifyCandidateClicked: bus is not connected.";
      return false;
    }
    if (!ibus_panel_service_) {
      LOG(ERROR) << "NotifyCandidateClicked: panel service is not available.";
      return false;
    }

    /* Send a D-Bus signal to ibus-daemon *asynchronously*. */
    ibus_panel_service_candidate_clicked(ibus_panel_service_,
                                         index,
                                         button,
                                         flags);
    return true;
  }

  // Registers a callback function which is called when IBusBus connection
  // status is changed.
  void MonitorInputMethodConnection(
      InputMethodConnectionChangeMonitorFunction connection_change_handler) {
    connection_change_handler_ = connection_change_handler;
  }

 private:
  // Installs gobject signal handlers to |ibus_|.
  void ConnectIBusSignals() {
    if (!ibus_) {
      return;
    }
    g_signal_connect(ibus_,
                     "connected",
                     G_CALLBACK(IBusBusConnectedCallback),
                     this);
    g_signal_connect(ibus_,
                     "disconnected",
                     G_CALLBACK(IBusBusDisconnectedCallback),
                     this);
  }

  // Removes gobject signal handlers from |ibus_|.
  void DisconnectIBusSignals() {
    if (!ibus_) {
      return;
    }
    g_signal_handlers_disconnect_by_func(
        ibus_,
        reinterpret_cast<gpointer>(G_CALLBACK(IBusBusConnectedCallback)),
        this);
    g_signal_handlers_disconnect_by_func(
        ibus_,
        reinterpret_cast<gpointer>(G_CALLBACK(IBusBusDisconnectedCallback)),
        this);
  }

  // Installs gobject signal handlers to |ibus_panel_service_|.
  void ConnectPanelServiceSignals() {
    if (!ibus_panel_service_) {
      return;
    }
    g_signal_connect(ibus_panel_service_,
                     "hide-auxiliary-text",
                     G_CALLBACK(HideAuxiliaryTextCallback),
                     this);
    g_signal_connect(ibus_panel_service_,
                     "hide-lookup-table",
                     G_CALLBACK(HideLookupTableCallback),
                     this);
    g_signal_connect(ibus_panel_service_,
                     "update-auxiliary-text",
                     G_CALLBACK(UpdateAuxiliaryTextCallback),
                     this);
    g_signal_connect(ibus_panel_service_,
                     "set-cursor-location",
                     G_CALLBACK(SetCursorLocationCallback),
                     this);
    g_signal_connect(ibus_panel_service_,
                     "update-lookup-table",
                     G_CALLBACK(UpdateLookupTableCallback),
                     this);
  }

  // Removes gobject signal handlers from |ibus_panel_service_|.
  void DisconnectPanelServiceSignals() {
    if (!ibus_panel_service_) {
      return;
    }
    g_signal_handlers_disconnect_by_func(
        ibus_panel_service_,
        reinterpret_cast<gpointer>(HideAuxiliaryTextCallback),
        this);
    g_signal_handlers_disconnect_by_func(
        ibus_panel_service_,
        reinterpret_cast<gpointer>(HideLookupTableCallback),
        this);
    g_signal_handlers_disconnect_by_func(
        ibus_panel_service_,
        reinterpret_cast<gpointer>(UpdateAuxiliaryTextCallback),
        this);
    g_signal_handlers_disconnect_by_func(
        ibus_panel_service_,
        reinterpret_cast<gpointer>(SetCursorLocationCallback),
        this);
    g_signal_handlers_disconnect_by_func(
        ibus_panel_service_,
        reinterpret_cast<gpointer>(UpdateLookupTableCallback),
        this);
  }

  // Handles "connected" signal from ibus-daemon.
  static void IBusBusConnectedCallback(IBusBus* bus, gpointer user_data) {
    LOG(WARNING) << "IBus connection is recovered.";
    g_return_if_fail(user_data);
    InputMethodUiStatusConnection* self
        = static_cast<InputMethodUiStatusConnection*>(user_data);
    if (!self->MaybeRestorePanelService()) {
      LOG(ERROR) << "MaybeRestorePanelService() failed";
      return;
    }
    if (self->connection_change_handler_) {
      self->connection_change_handler_(self->input_method_library_, true);
    }
  }

  // Handles "disconnected" signal from ibus-daemon. Releases the
  // |ibus_panel_service_| object since the connection the service has will be
  // destroyed soon.
  static void IBusBusDisconnectedCallback(IBusBus* bus, gpointer user_data) {
    LOG(WARNING) << "IBus connection is terminated!";
    g_return_if_fail(user_data);
    InputMethodUiStatusConnection* self
        = static_cast<InputMethodUiStatusConnection*>(user_data);
    if (self->ibus_panel_service_) {
      self->DisconnectPanelServiceSignals();
      // Since the connection being disconnected is currently mutex-locked,
      // we can't unref the panel service object directly here. Because when the
      // service object is deleted, the connection, which the service also has,
      // will be locked again. To avoid deadlock, we use g_idle_add instead.
      g_object_set_data(G_OBJECT(self->ibus_), kPanelObjectKey, NULL);
      g_idle_add(ReleasePanelService, self->ibus_panel_service_);
      self->ibus_panel_service_ = NULL;
    }

    if (self->connection_change_handler_) {
      self->connection_change_handler_(self->input_method_library_, false);
    }
  }

  // Releases |ibus_panel_service_|. See the comment above.
  static gboolean ReleasePanelService(gpointer user_data) {
    g_return_val_if_fail(IBUS_IS_PANEL_SERVICE(user_data), FALSE);
    g_object_unref(user_data);
    return FALSE;  // stop the idle timer.
  }

  // Handles IBusPanelService's |HideAuxiliaryText| method call.
  // Calls |hide_auxiliary_text| in |monitor_functions|.
  static void HideAuxiliaryTextCallback(IBusPanelService *panel,
                                        gpointer user_data) {
    g_return_if_fail(user_data);
    InputMethodUiStatusConnection* self
        = static_cast<InputMethodUiStatusConnection*>(user_data);
    g_return_if_fail(self->monitor_functions_.hide_auxiliary_text);
    self->monitor_functions_.hide_auxiliary_text(self->input_method_library_);
  }

  // Handles IBusPanelService's |HideLookupTable| method call.
  // Calls |hide_lookup_table| in |monitor_functions|.
  static void HideLookupTableCallback(IBusPanelService *panel,
                                      gpointer user_data) {
    g_return_if_fail(user_data);
    InputMethodUiStatusConnection* self
        = static_cast<InputMethodUiStatusConnection*>(user_data);
    g_return_if_fail(self->monitor_functions_.hide_lookup_table);
    self->monitor_functions_.hide_lookup_table(self->input_method_library_);
  }

  // Handles IBusPanelService's |UpdateAuxiliaryText| method call.
  // Converts IBusText to a std::string, and calls |update_auxiliary_text| in
  // |monitor_functions|
  static void UpdateAuxiliaryTextCallback(IBusPanelService *panel,
                                          IBusText *text,
                                          gboolean visible,
                                          gpointer user_data) {
    g_return_if_fail(text);
    g_return_if_fail(text->text);
    g_return_if_fail(user_data);
    InputMethodUiStatusConnection* self
        = static_cast<InputMethodUiStatusConnection*>(user_data);
    g_return_if_fail(self->monitor_functions_.update_auxiliary_text);
    // Convert IBusText to a std::string. IBusText is an attributed text,
    const std::string simple_text = text->text;
    self->monitor_functions_.update_auxiliary_text(
        self->input_method_library_, simple_text, visible == TRUE);
  }

  // Handles IBusPanelService's |SetCursorLocation| method call.
  // Calls |set_cursor_location| in |monitor_functions|.
  static void SetCursorLocationCallback(IBusPanelService *panel,
                                        gint x,
                                        gint y,
                                        gint width,
                                        gint height,
                                        gpointer user_data) {
    g_return_if_fail(user_data);
    InputMethodUiStatusConnection* self
        = static_cast<InputMethodUiStatusConnection*>(user_data);
    g_return_if_fail(self->monitor_functions_.set_cursor_location);
    self->monitor_functions_.set_cursor_location(
        self->input_method_library_, x, y, width, height);
  }

  // Handles IBusPanelService's |UpdateLookupTable| method call.
  // Creates an InputMethodLookupTable object and calls |update_lookup_table| in
  // |monitor_functions|
  static void UpdateLookupTableCallback(IBusPanelService *panel,
                                        IBusLookupTable *table,
                                        gboolean visible,
                                        gpointer user_data) {
    g_return_if_fail(table);
    g_return_if_fail(user_data);
    InputMethodUiStatusConnection* self
        = static_cast<InputMethodUiStatusConnection*>(user_data);
    g_return_if_fail(self->monitor_functions_.update_lookup_table);

    InputMethodLookupTable lookup_table;
    lookup_table.visible = (visible == TRUE);

    // Copy the orientation information.
    const gint orientation = ibus_lookup_table_get_orientation(table);
    if (orientation == IBUS_ORIENTATION_VERTICAL) {
      lookup_table.orientation = InputMethodLookupTable::kVertical;
    } else if (orientation == IBUS_ORIENTATION_HORIZONTAL) {
      lookup_table.orientation = InputMethodLookupTable::kHorizontal;
    }

    // Copy candidates and annotations to |lookup_table|.
    for (int i = 0; ; i++) {
      IBusText *text = ibus_lookup_table_get_candidate(table, i);
      if (!text) {
        break;
      }

      if (!text->attrs || !text->attrs->attributes) {
        lookup_table.candidates.push_back(text->text);
        lookup_table.annotations.push_back("");
        continue;
      }

      // Divide candidate and annotation by specific attribute.
      const guint length = text->attrs->attributes->len;
      for (int j = 0; ; j++) {
        IBusAttribute *attr = ibus_attr_list_get(text->attrs, j);

        // The candidate does not have annotation.
        if (!attr) {
          lookup_table.candidates.push_back(text->text);
          lookup_table.annotations.push_back("");
          break;
        }

        // Check that the attribute indicates annotation.
        if (IsAnnotation(attr) && j + 1 == static_cast<int>(length)) {
        const std::wstring candidate_word =
            UTF8ToWide(text->text).substr(0, attr->start_index);
        lookup_table.candidates.push_back(WideToUTF8(candidate_word));

        const std::wstring annotation_word =
            UTF8ToWide(text->text).substr(attr->start_index, attr->end_index);
        lookup_table.annotations.push_back(WideToUTF8(annotation_word));

        break;
        }
      }
    }
    DCHECK_EQ(lookup_table.candidates.size(),
              lookup_table.annotations.size());

    // Copy labels to |lookup_table|.
    for (int i = 0; ; i++) {
      IBusText *text = ibus_lookup_table_get_label(table, i);
      if (!text) {
        break;
      }
      lookup_table.labels.push_back(text->text);
    }

    lookup_table.cursor_absolute_index =
        ibus_lookup_table_get_cursor_pos(table);
    lookup_table.page_size = ibus_lookup_table_get_page_size(table);
    // Ensure that the page_size is non-zero to avoid div-by-zero error.
    if (lookup_table.page_size <= 0) {
      LOG(DFATAL) << "Invalid page size: " << lookup_table.page_size;
      lookup_table.page_size = 1;
    }

    self->monitor_functions_.update_lookup_table(
        self->input_method_library_, lookup_table);
  }

  InputMethodUiStatusMonitorFunctions monitor_functions_;
  InputMethodConnectionChangeMonitorFunction connection_change_handler_;
  void* input_method_library_;
  IBusBus* ibus_;
  IBusPanelService* ibus_panel_service_;
};

//
// cros APIs
//

// The function will be bound to chromeos::MonitorInputMethodUiStatus with
// dlsym() in load.cc so it needs to be in the C linkage, so the symbol
// name does not get mangled.
extern "C"
InputMethodUiStatusConnection* ChromeOSMonitorInputMethodUiStatus(
    const InputMethodUiStatusMonitorFunctions& monitor_functions,
    void* input_method_library) {
  DLOG(INFO) << "MonitorInputMethodUiStatus";

  InputMethodUiStatusConnection* connection =
      new InputMethodUiStatusConnection(monitor_functions,
                                        input_method_library);

  // It's totally fine if ConnectToIBus() fails here, as we'll get "connected"
  // gobject signal once the connection becomes ready.
  if (connection->ConnectToIBus()) {
    connection->MaybeRestorePanelService();
  }
  return connection;
}

extern "C"
void ChromeOSDisconnectInputMethodUiStatus(
    InputMethodUiStatusConnection* connection) {
  DLOG(INFO) << "DisconnectInputMethodUiStatus";
  delete connection;
}

extern "C"
void ChromeOSNotifyCandidateClicked(InputMethodUiStatusConnection* connection,
                                    int index, int button, int flags) {
  DLOG(INFO) << "NotifyCandidateClicked";
  DCHECK(connection);
  if (connection) {
    connection->NotifyCandidateClicked(index, button, flags);
  }
}

extern "C"
void ChromeOSMonitorInputMethodConnection(
    InputMethodUiStatusConnection* connection,
    InputMethodConnectionChangeMonitorFunction connection_change_handler) {
  DLOG(INFO) << "MonitorInputMethodConnection";
  DCHECK(connection);
  if (connection) {
    connection->MonitorInputMethodConnection(connection_change_handler);
  }
}

}  // namespace chromeos
