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

#include <string>

#include "base/const.h"
#include "base/file_util.h"
#include "base/logging.h"
#include "base/system_util.h"
#include "client/client.h"  // For client interface
#include "unix/ibus/message_translator.h"
#include "unix/ibus/mozc_engine_property.h"
#include "unix/ibus/path_util.h"

// On Gnome Shell with IBus 1.5, new property named "symbol" is used to
// represent the mode indicator on the system panel. Note that "symbol" does
// not exist in IBus 1.4.x.
#if IBUS_CHECK_VERSION(1, 5, 0)
#define MOZC_IBUS_HAS_SYMBOL
#endif  // IBus >= 1.5

namespace mozc {
namespace ibus {

namespace {

// A key which associates an IBusProperty object with MozcEngineProperty.
const char kGObjectDataKey[] = "ibus-mozc-aux-data";

// Icon path for MozcTool
const char kMozcToolIconPath[] = "tool.png";

// Returns true if mozc_tool is installed.
bool IsMozcToolAvailable() {
  return FileUtil::FileExists(SystemUtil::GetToolPath());
}

bool GetDisabled(IBusEngine *engine) {
  bool disabled = false;
#if defined(MOZC_ENABLE_IBUS_INPUT_PURPOSE)
  guint purpose = IBUS_INPUT_PURPOSE_FREE_FORM;
  guint hints = IBUS_INPUT_HINT_NONE;
  ibus_engine_get_content_type(engine, &purpose, &hints);
  disabled = (purpose == IBUS_INPUT_PURPOSE_PASSWORD ||
              purpose == IBUS_INPUT_PURPOSE_PIN);
#endif  // MOZC_ENABLE_IBUS_INPUT_PURPOSE
  return disabled;
}

// Some users expect that Mozc is turned off by default on IBus 1.5.0 and later.
// https://code.google.com/p/mozc/issues/detail?id=201
// On IBus 1.4.x, IBus expects that an IME should always be turned on and
// IME on/off keys are handled by IBus itself rather than each IME.
#if IBUS_CHECK_VERSION(1, 5, 0)
const bool kActivatedOnLaunch = false;
#else
const bool kActivatedOnLaunch = true;
#endif  // IBus>=1.5.0

}  // namespace

PropertyHandler::PropertyHandler(MessageTranslatorInterface *translator,
                                 client::ClientInterface *client)
    : prop_root_(ibus_prop_list_new()),
      prop_composition_mode_(NULL),
      prop_mozc_tool_(NULL),
      client_(client),
      translator_(translator),
      original_composition_mode_(kMozcEngineInitialCompositionMode),
      is_activated_(kActivatedOnLaunch),
      is_disabled_(false) {
  commands::SessionCommand command;
  if (is_activated_) {
    command.set_type(commands::SessionCommand::TURN_ON_IME);
  } else {
    command.set_type(commands::SessionCommand::TURN_OFF_IME);
  }
  command.set_composition_mode(original_composition_mode_);
  commands::Output output;
  if (!client->SendCommand(command, &output)) {
    LOG(ERROR) << "SendCommand failed";
  }

  AppendCompositionPropertyToPanel();
  AppendToolPropertyToPanel();

  // We have to sink |prop_root_| as well so ibus_engine_register_properties()
  // in FocusIn() does not destruct it.
  g_object_ref_sink(prop_root_);
}

PropertyHandler::~PropertyHandler() {
  if (prop_composition_mode_) {
    // The ref counter will drop to one.
    g_object_unref(prop_composition_mode_);
    prop_composition_mode_ = NULL;
  }

  if (prop_mozc_tool_) {
    // The ref counter will drop to one.
    g_object_unref(prop_mozc_tool_);
    prop_mozc_tool_ = NULL;
  }

  if (prop_root_) {
    // Destroy all objects under the root.
    g_object_unref(prop_root_);
    prop_root_ = NULL;
  }
}

void PropertyHandler::Register(IBusEngine *engine) {
  ibus_engine_register_properties(engine, prop_root_);
  UpdateContentType(engine);
}

// TODO(nona): do not use kMozcEngine*** directory.
void PropertyHandler::AppendCompositionPropertyToPanel() {
  if (kMozcEngineProperties == NULL || kMozcEnginePropertiesSize == 0) {
    return;
  }

  // |sub_prop_list| is a radio menu which is shown when a button in the
  // language panel (i.e. |prop_composition_mode_| below) is clicked.
  IBusPropList *sub_prop_list = ibus_prop_list_new();

  // Create items for the radio menu.
  const commands::CompositionMode initial_mode = is_activated_ ?
      original_composition_mode_ :
      kMozcEnginePropertyIMEOffState->composition_mode;

  string icon_path_for_panel;
  const char *mode_symbol = NULL;
  for (size_t i = 0; i < kMozcEnginePropertiesSize; ++i) {
    const MozcEngineProperty &entry = kMozcEngineProperties[i];
    IBusText *label = ibus_text_new_from_string(
        translator_->MaybeTranslate(entry.label).c_str());
    IBusPropState state = PROP_STATE_UNCHECKED;
    if (entry.composition_mode == initial_mode) {
      state = PROP_STATE_CHECKED;
      icon_path_for_panel = GetIconPath(entry.icon);
      mode_symbol = entry.label_for_panel;
    }
    IBusProperty *item = ibus_property_new(entry.key,
                                           PROP_TYPE_RADIO,
                                           label,
                                           NULL /* icon */,
                                           NULL /* tooltip */,
                                           TRUE /* sensitive */,
                                           TRUE /* visible */,
                                           state,
                                           NULL /* sub props */);
    g_object_set_data(G_OBJECT(item), kGObjectDataKey, (gpointer)&entry);
    ibus_prop_list_append(sub_prop_list, item);
    // |sub_prop_list| owns |item| by calling g_object_ref_sink for the |item|.
  }
  DCHECK(!icon_path_for_panel.empty());
  DCHECK(mode_symbol != NULL);

  const string &mode_label =
      translator_->MaybeTranslate("Input Mode") + " (" + mode_symbol + ")";
  IBusText *label = ibus_text_new_from_string(mode_label.c_str());

  // The label of |prop_composition_mode_| is shown in the language panel.
  // Note that the property name "InputMode" is hard-coded in the Gnome shell.
  // Do not change the name. Othewise the Gnome shell fails to recognize that
  // this property indicates Mozc's input mode.
  // See /usr/share/gnome-shell/js/ui/status/keyboard.js for details.
  prop_composition_mode_ = ibus_property_new("InputMode",
                                             PROP_TYPE_MENU,
                                             label,
                                             icon_path_for_panel.c_str(),
                                             NULL /* tooltip */,
                                             TRUE /* sensitive */,
                                             TRUE /* visible */,
                                             PROP_STATE_UNCHECKED,
                                             sub_prop_list);

  // Gnome shell uses symbol property for the mode indicator text icon iff the
  // property name is "InputMode".
#ifdef MOZC_IBUS_HAS_SYMBOL
  IBusText *symbol = ibus_text_new_from_static_string(mode_symbol);
  ibus_property_set_symbol(prop_composition_mode_, symbol);
#endif  // MOZC_IBUS_HAS_SYMBOL

  // Likewise, |prop_composition_mode_| owns |sub_prop_list|. We have to sink
  // |prop_composition_mode_| here so ibus_engine_update_property() call in
  // PropertyActivate() does not destruct the object.
  g_object_ref_sink(prop_composition_mode_);

  ibus_prop_list_append(prop_root_, prop_composition_mode_);
}

void PropertyHandler::UpdateContentTypeImpl(IBusEngine *engine,
                                            bool disabled) {
  const bool prev_is_disabled = is_disabled_;
  is_disabled_ = disabled;
  if (prev_is_disabled == is_disabled_) {
    return;
  }
  const auto visible_mode = (prev_is_disabled && !is_disabled_ && IsActivated())
      ? original_composition_mode_ :
        kMozcEnginePropertyIMEOffState->composition_mode;
  UpdateCompositionModeIcon(engine, visible_mode);
}

void PropertyHandler::ResetContentType(IBusEngine *engine) {
  UpdateContentTypeImpl(engine, false);
}

void PropertyHandler::UpdateContentType(IBusEngine *engine) {
  UpdateContentTypeImpl(engine, GetDisabled(engine));
}

// TODO(nona): do not use kMozcEngine*** directory.
void PropertyHandler::AppendToolPropertyToPanel() {
  if (kMozcEngineToolProperties == NULL || kMozcEngineToolPropertiesSize == 0 ||
      !IsMozcToolAvailable()) {
    return;
  }

  // |sub_prop_list| is a radio menu which is shown when a button in the
  // language panel (i.e. |prop_composition_mode_| below) is clicked.
  IBusPropList *sub_prop_list = ibus_prop_list_new();

  for (size_t i = 0; i < kMozcEngineToolPropertiesSize; ++i) {
    const MozcEngineToolProperty &entry = kMozcEngineToolProperties[i];
    IBusText *label = ibus_text_new_from_string(
        translator_->MaybeTranslate(entry.label).c_str());
    // TODO(yusukes): It would be better to use entry.icon here?
    IBusProperty *item = ibus_property_new(entry.mode,
                                           PROP_TYPE_NORMAL,
                                           label,
                                           NULL /* icon */,
                                           NULL /* tooltip */,
                                           TRUE,
                                           TRUE,
                                           PROP_STATE_UNCHECKED,
                                           NULL);
    g_object_set_data(G_OBJECT(item), kGObjectDataKey, (gpointer)&entry);
    ibus_prop_list_append(sub_prop_list, item);
  }

  IBusText *tool_label = ibus_text_new_from_string(
      translator_->MaybeTranslate("Tools").c_str());
  const string icon_path = GetIconPath(kMozcToolIconPath);
  prop_mozc_tool_ = ibus_property_new("MozcTool",
                                      PROP_TYPE_MENU,
                                      tool_label,
                                      icon_path.c_str(),
                                      NULL /* tooltip */,
                                      TRUE /* sensitive */,
                                      TRUE /* visible */,
                                      PROP_STATE_UNCHECKED,
                                      sub_prop_list);

  // Likewise, |prop_mozc_tool_| owns |sub_prop_list|. We have to sink
  // |prop_mozc_tool_| here so ibus_engine_update_property() call in
  // PropertyActivate() does not destruct the object.
  g_object_ref_sink(prop_mozc_tool_);

  ibus_prop_list_append(prop_root_, prop_mozc_tool_);
}

void PropertyHandler::Update(IBusEngine *engine,
                             const commands::Output &output) {
  if (IsDisabled()) {
    return;
  }

  if (output.has_status() &&
      (output.status().activated() != is_activated_ ||
       output.status().mode() != original_composition_mode_)) {
    if (output.status().activated()) {
      UpdateCompositionModeIcon(engine, output.status().mode());
    } else {
      DCHECK(kMozcEnginePropertyIMEOffState);
      UpdateCompositionModeIcon(
          engine, kMozcEnginePropertyIMEOffState->composition_mode);
    }
    is_activated_ = output.status().activated();
    original_composition_mode_ = output.status().mode();
  }
}

void PropertyHandler::UpdateCompositionModeIcon(
    IBusEngine *engine, const commands::CompositionMode new_composition_mode) {
  if (prop_composition_mode_ == NULL) {
    return;
  }

  const MozcEngineProperty *entry = NULL;
  for (size_t i = 0; i < kMozcEnginePropertiesSize; ++i) {
    if (kMozcEngineProperties[i].composition_mode ==
        new_composition_mode) {
      entry = &(kMozcEngineProperties[i]);
      break;
    }
  }
  DCHECK(entry);

  for (guint prop_index = 0; ; ++prop_index) {
    IBusProperty *prop = ibus_prop_list_get(
        ibus_property_get_sub_props(prop_composition_mode_), prop_index);
    if (prop == NULL) {
      break;
    }
    if (!g_strcmp0(entry->key, ibus_property_get_key(prop))) {
      // Update the language panel.
      ibus_property_set_icon(prop_composition_mode_,
                             GetIconPath(entry->icon).c_str());
      // Update the radio menu item.
      ibus_property_set_state(prop, PROP_STATE_CHECKED);
    } else {
      ibus_property_set_state(prop, PROP_STATE_UNCHECKED);
    }
    // No need to call unref since ibus_prop_list_get does not add ref.
  }

  const char *mode_symbol = entry->label_for_panel;
  // Update the text icon for Gnome shell.
#ifdef MOZC_IBUS_HAS_SYMBOL
  IBusText *symbol = ibus_text_new_from_static_string(mode_symbol);
  ibus_property_set_symbol(prop_composition_mode_, symbol);
#endif  // MOZC_IBUS_HAS_SYMBOL

  const string &mode_label =
      translator_->MaybeTranslate("Input Mode") + " (" + mode_symbol + ")";
  IBusText *label = ibus_text_new_from_string(mode_label.c_str());
  ibus_property_set_label(prop_composition_mode_, label);

  ibus_engine_update_property(engine, prop_composition_mode_);
}

void PropertyHandler::SetCompositionMode(
    IBusEngine *engine, commands::CompositionMode composition_mode) {
  commands::SessionCommand command;
  commands::Output output;

  // In the case of Mozc, there are two state values of IME, IMEOn/IMEOff and
  // composition_mode. However in IBus we can only control composition mode, not
  // IMEOn/IMEOff. So we use one composition state as IMEOff and the others as
  // IMEOn. This setting can be configured with setting
  // kMozcEnginePropertyIMEOffState. If kMozcEnginePropertyIMEOffState is NULL,
  // it means current IME should not be off.
  if (kMozcEnginePropertyIMEOffState
      && is_activated_
      && composition_mode == kMozcEnginePropertyIMEOffState->composition_mode) {
    command.set_type(commands::SessionCommand::TURN_OFF_IME);
    command.set_composition_mode(original_composition_mode_);
    client_->SendCommand(command, &output);
  } else {
    command.set_type(commands::SessionCommand::SWITCH_INPUT_MODE);
    command.set_composition_mode(composition_mode);
    client_->SendCommand(command, &output);
  }
  DCHECK(output.has_status());
  original_composition_mode_ = output.status().mode();
  is_activated_ = output.status().activated();
}

void PropertyHandler::ProcessPropertyActivate(IBusEngine *engine,
                                              const gchar *property_name,
                                              guint property_state) {
  if (IsDisabled()) {
    return;
  }

  if (prop_mozc_tool_) {
    for (guint prop_index = 0; ; ++prop_index) {
      IBusProperty *prop = ibus_prop_list_get(
          ibus_property_get_sub_props(prop_mozc_tool_), prop_index);
      if (prop == NULL) {
        break;
      }
      if (!g_strcmp0(property_name, ibus_property_get_key(prop))) {
        const MozcEngineToolProperty *entry =
            reinterpret_cast<const MozcEngineToolProperty*>(
                g_object_get_data(G_OBJECT(prop), kGObjectDataKey));
        DCHECK(entry->mode);
        if (!client_->LaunchTool(entry->mode, "")) {
          LOG(ERROR) << "cannot launch: " << entry->mode;
        }
        return;
      }
    }
  }

  if (property_state != PROP_STATE_CHECKED) {
    return;
  }

  if (prop_composition_mode_) {
    for (guint prop_index = 0; ; ++prop_index) {
      IBusProperty *prop = ibus_prop_list_get(
          ibus_property_get_sub_props(prop_composition_mode_), prop_index);
      if (prop == NULL) {
        break;
      }
      if (!g_strcmp0(property_name, ibus_property_get_key(prop))) {
        const MozcEngineProperty *entry =
            reinterpret_cast<const MozcEngineProperty*>(
                g_object_get_data(G_OBJECT(prop), kGObjectDataKey));
        SetCompositionMode(engine, entry->composition_mode);
        UpdateCompositionModeIcon(
            engine, entry->composition_mode);
        break;
      }
    }
  }
}

bool PropertyHandler::IsActivated() const {
  return is_activated_;
}

bool PropertyHandler::IsDisabled() const {
  return is_disabled_;
}

commands::CompositionMode PropertyHandler::GetOriginalCompositionMode() const {
  return original_composition_mode_;
}

}  // namespace ibus
}  // namespace mozc
