# -*- mode: shell-script; sh-basic-offset: 2; sh-indentation: 2; indent-tab-mode: nil -*-
# imsettings-functions
# Copyright (C) 2013-2016 Akira TAGOH
#
# Authors:
#   Akira TAGOH  <tagoh@redhat.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the
# Free Software Foundation, Inc., 51 Franklin Street, Fifth
# Floor, Boston, MA  02110-1301  USA

LOGDIR="${XDG_CACHE_HOME:-$HOME/.cache}/imsettings"
LOGFILE="$LOGDIR/log"

function log_init() {
  if [ -z "$DRY_RUN" ]; then
    if [ -f "$HOME"/.imsettings.log ]; then
      mv "$HOME"/.imsettings.log "$LOGFILE".bak
    fi
    [ -f "$LOGFILE" ] && mv "$LOGFILE" "$LOGFILE".bak
    touch "$LOGFILE"
  fi
}

function log() {
  echo "$@" >> "$LOGFILE"
}

function is_dbus_enabled() {
  /usr/libexec/imsettings-check --check-dbus
  [ $? -eq 0 ]
}

function is_imsettings_enabled() {
  [ -z "$DISABLE_IMSETTINGS" ] && is_dbus_enabled
}

function check_imsettings_capability() {
  mod=$1
  /usr/libexec/imsettings-check --check-modules >/dev/null
  ret=$?
  if [ $ret -eq 0 ]; then
    /usr/libexec/imsettings-check --check-modulesettings -d | grep "$mod" >/dev/null
    ret=$?
  fi
  return $ret
}

function lookup_desktop() {
  ret=$(cat "$1")
  case $ret in
    cinnamon*)
      echo -n "cinnamon"
      ;;
    gnome*)
      echo -n "gnome"
      ;;
    kde*|plasma)
      echo -n "kde"
      ;;
    lxsession*)
      echo -n "LXDE"
      ;;
    mate*)
      echo -n "mate"
      ;;
    xfce*)
      echo -n "xfce"
      ;;
    *)
      echo -n "unknown"
      ;;
  esac
}

function get_desktop() {
  if [ -n "$XDG_CURRENT_DESKTOP" ]; then
    GUESS_DESKTOP="\$XDG_CURRENT_DESKTOP"
    echo -n "$XDG_CURRENT_DESKTOP"
  elif [ -n "$IMSETTINGS_DESKTOP" ]; then
    GUESS_DESKTOP="\$IMSETTINGS_DESKTOP"
    echo -n "$IMSETTINGS_DESKTOP"
  elif [ -n "$GDMSESSION" ]; then
    GUESS_DESKTOP="\$GDMSESSION"
    echo -n "$GDMSESSION"
  elif [ -n "$DESKTOP_SESSION" ]; then
    GUESS_DESKTOP="\$DESKTOP_SESSION"
    if [ "$DESKTOP_SESSION" == "default" ]; then
      if [ -x "$HOME/.xsession" ]; then
        GUESS_DESKTOP="$HOME/.xsession"
      elif [ -x "$HOME/.Xclients" ]; then
        GUESS_DESKTOP="$HOME/.Xclients"
      elif [ -f "/etc/sysconfig/desktop" ]; then
        GUESS_DESKTOP=" /etc/sysconfig/desktop"
        . /etc/sysconfig/desktop
        echo -n "$DESKTOP"
      else
        echo -n "unknown"
      fi
    else
      echo -n "$DESKTOP_SESSION"
    fi
    [ "${GUESS_DESKTOP:0:1}" == "/" ] && lookup_desktop "$GUESS_DESKTOP"
  else
    echo -n "unknown"
  fi
  if [ -n "$XDG_SESSION_TYPE" ] && [ "$XDG_SESSION_TYPE" = "wayland" ]; then
    GUESS_DESKTOP="\$XDG_SESSION_TYPE"
    echo "-wayland"
  else
    echo ""
  fi
}

function is_gtk_supported() {
  [ -n "$IMSETTINGS_DISABLE_DESKTOP_CHECK" ] && return 0
  case "$(get_desktop|tr '[:upper:]' '[:lower:]')" in
    *wayland)
      if check_imsettings_capability gsettings; then
        return 0
      fi
      ;;
    cinnamon*)
      if check_imsettings_capability cinnamon-gsettings; then
        return 0
      fi
      ;;
    *gnome|gnome*|openbox)
      if check_imsettings_capability gconf || check_imsettings_capability gsettings; then
        return 0
      fi
      ;;
    lxde)
      if check_imsettings_capability lxde; then
        return 0
      fi
      ;;
    mate)
      if check_imsettings_capability mateconf || check_imsettings_capability mate-gsettings; then
        return 0
      fi
      ;;
    xfce*)
      if check_imsettings_capability xfce; then
        return 0
      fi
      ;;
    *)
      ;;
  esac

  return 1
}

function is_qt_supported() {
  [ -n "$IMSETTINGS_DISABLE_DESKTOP_CHECK" ] && return 0
  case "$(get_desktop|tr '[:upper:]' '[:lower:]')" in
    *wayland)
      return 0
      ;;
    *)
      ;;
  esac

  return 1
}

function is_xim_supported() {
## Disable XIM support
#  [ -n "$IMSETTINGS_DISABLE_DESKTOP_CHECK" ] && return 0
#  if check_imsettings_capability xim; then
#    return 0
#  fi

  return 1
}

function is_desktop_supported() {
  /usr/libexec/imsettings-check --check-desktop "$(get_desktop)" >/dev/null
  [ $? -eq 0 ]
}

function is_action_needed() {
  ret=0
  for i in ${IMSETTINGS_IGNORE_SESSION//,/ }; do
    if [[ "$(get_desktop|tr '[:upper:]' '[:lower:]')" == $(echo $i|tr '[:upper:]' '[:lower:]') ]]; then
      ret=1
    fi
  done
  return $ret
}

function setup_gtk_immodule() {
  if ! is_action_needed || is_imsettings_enabled && is_gtk_supported; then
    # Ensure GTK_IM_MODULE is empty. otherwise GTK+ doesn't pick up immodule through XSETTINGS
    unset GTK_IM_MODULE
  else
    [ -n "$GTK_IM_MODULE" ] && export GTK_IM_MODULE
  fi
}

function setup_qt_immodule() {
  if ! is_action_needed; then
    unset QT_IM_MODULE
  fi
  if is_imsettings_enabled && is_qt_supported; then
    # FIXME: Qt doesn't support XSETTINGS for immodule yet.
    #        We still need to go with the older way.
    [ -n "$QT_IM_MODULE" ] && export QT_IM_MODULE
  else
    [ -n "$QT_IM_MODULE" ] && export QT_IM_MODULE
  fi
}

function setup_xim() {
  if is_imsettings_enabled && is_xim_supported; then
    # setup XMODIFIERS
    XMODIFIERS="@im=imsettings"
    export XMODIFIERS
  else
    [ -z "$XMODIFIERS" ] && [ -n "$XIM" ] && XMODIFIERS="@im=$XIM"
    [ -n "$XMODIFIERS" ] && export XMODIFIERS
  fi
}

function run_imsettings() {
  print_info
  if [ -n "$DRY_RUN" ]; then
    log "*** DRY RUN MODE: running IM through imsettings"
  elif ! is_action_needed; then
    log "No action required"
  else
    if [ -n "$IMSETTINGS_INTEGRATE_DESKTOP" ] && [ "$IMSETTINGS_INTEGRATE_DESKTOP" = "no" ]; then
      which imsettings-switch > /dev/null 2>&1 && LANG="$tmplang" imsettings-switch -n "$IMSETTINGS_MODULE" || :
      # NOTE: We don't bring up imsettings-xim nor imsettings-applet here to support XIM.
      #       imsettings-applet will starts through XDG autostart mechanism.
      #       If the desktop doesn't support that, this function shouldn't be invoked.
      #       but run_xim() instead.
    fi
  fi
}

function run_xim() {
  print_info
  if [ -n "$DRY_RUN" ]; then
    log "*** DRY RUN MODE: running IM without imsettings"
  elif ! is_action_needed; then
    log "No action required"
  else
    DISABLE_IMSETTINGS=true
    export DISABLE_IMSETTINGS

    # execute XIM_PROGRAM
    [ -n "$XIM_PROGRAM" ] && which "$XIM_PROGRAM" > /dev/null 2>&1 && LANG="$tmplang" "$XIM_PROGRAM" "$XIM_ARGS" > "$LOGFILE" 2>&1 &
  fi
}

function print_result() {
  $1
  if [ $? -eq 0 ]; then
    log yes
  else
    log no
  fi
}

function print_info() {
  log "imsettings information"
  log "=========================="
  log "XINPUTRC: $READ_XINPUTRC"
  if [ "x$READ_XINPUTRC" != "xN/A" ]; then
    log "$(stat "$READ_XINPUTRC"|sed -e 's/\(.*\)/\t\1/g')"
  fi
  log -n "Is DBus enabled: "
  print_result is_dbus_enabled
  log -n "Is imsettings enabled: "
  print_result is_imsettings_enabled
  log -n "Is GTK+ supported: "
  print_result is_gtk_supported
  log -n "Is Qt supported: "
  print_result is_qt_supported
  log -n "Is Action needed: "
  print_result is_action_needed
  log "DESKTOP: $(get_desktop)"
  get_desktop > /dev/null
  log "GUESS_DESKTOP: $GUESS_DESKTOP"
  log "DISABLE_IMSETTINGS: $DISABLE_IMSETTINGS"
  log "IMSETTINGS_DISABLE_DESKTOP_CHECK: $IMSETTINGS_DISABLE_DESKTOP_CHECK"
  log "DBUS_SESSION_BUS_ADDRESS: $DBUS_SESSION_BUS_ADDRESS"
  log "GTK_IM_MODULE: $GTK_IM_MODULE"
  log "QT_IM_MODULE: $QT_IM_MODULE"
  log "XMODIFIERS: $XMODIFIERS"
  log "IMSETTINGS_MODULE: $IMSETTINGS_MODULE"
  log "IMSETTINGS_INTEGRATE_DESKTOP: $IMSETTINGS_INTEGRATE_DESKTOP"
  log "IMSETTINGS_DISABLE_SYS_XINPUTRC: $IMSETTINGS_DISABLE_SYS_XINPUTRC"
  log "IMSETTINGS_DISABLE_USER_XINPUTRC: $IMSETTINGS_DISABLE_USER_XINPUTRC"
  log "IMSETTINGS_IGNORE_SESSION: $IMSETTINGS_IGNORE_SESSION"
  log ""
}
