#!/usr/bin/bash

# Copyright (c) 2015-2022 Samuel Thibault <samuel.thibault@ens-lyon.org>
# All rights reserved.
# 
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 2. 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.
# 
# THIS SOFTWARE IS PROVIDED BY Samuel Thibault ``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 Samuel Thibault 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.

test_package()
{
  status="$(dpkg-query -W -f '${db:Status-Status}' $1 2> /dev/null)"
  [ "$status" = "installed" -o "$status" = "installedinstalled" ]
}

echo Info
echo "INFO: session type '$XDG_SESSION_TYPE'"
echo "INFO: VT '$XDG_VTNR'"
echo "INFO: session desktop '$XDG_SESSION_DESKTOP'"
echo "INFO: current desktop '$XDG_CURRENT_DESKTOP'"
echo "INFO: display variables $(printenv | grep DISPLAY | tr $'\n' ' ')"

if test -f /etc/debian_version
then
  echo
  echo Packages

  if test_package at-spi2-core
  then
    echo "PASS: at-spi2-core installed"
  else
    echo "FAIL: at-spi2-core not installed, AT-SPI bus can't be launched"
  fi

  if test_package libgail-common
  then
    echo "PASS: libgail-common installed"
  else
    echo "FAIL: libgail-common not installed, GTK2 applications will not be accessible"
  fi

  if test_package libatk-adaptor
  then
    echo "PASS: libatk-adaptor installed"
  else
    echo "FAIL: libatk-adaptor not installed, GTK2 applications will not be accessible"
  fi

  if test_package qt-at-spi
  then
    echo "PASS: qt-at-spi installed"
  else
    echo "FAIL: qt-at-spi not installed, Qt4 applications will not be accessible"
  fi

  if test_package libatk-wrapper-java
  then
    echo "PASS: libatk-wrapper-java installed"
  else
    echo "FAIL: libatk-wrapper-java not installed, Java Swing applications will not be accessible"
  fi
fi

echo
echo Running environment

user_commands="$(ps -x -o cmd)"
all_commands="$(ps -ax -o cmd)"

check_proc()
{
  if [ "${user_commands/*$1*/found}" != found ]
  then
    echo "FAIL: $1 is not running as user $USER"
    if [ "${all_commands/*$1*/found}" == found ]
    then
      echo "but another $1 is running as another user (though perhaps on another DISPLAY)"
    fi
  else
    echo "PASS: $1 is running as user $USER"
  fi
}

check_proc at-spi-bus-launcher
check_proc at-spi2-registryd

if [ -n "$AT_SPI_BUS_ADDRESS" ]
then
  echo "INFO: \$AT_SPI_BUS_ADDRESS contains $AT_SPI_BUS_ADDRESS"
fi

num=${DISPLAY#*:}
num=${num%\.*}
session_address=
if [ -f "/var/lib/dbus/machine-id" ]
then
    file="$HOME/.dbus/session-bus/$(cat /var/lib/dbus/machine-id)-$num"
    if [ -f "$file" ]
    then
      session_address=$(grep ^DBUS_SESSION_BUS_ADDRESS "$file" | cut -d '=' -f 2- | tr -d "'")
    fi
fi
if [ -z "$DBUS_SESSION_BUS_ADDRESS" ]
then
  echo "FAIL: no session bus address in \$DBUS_SESSION_BUS_ADDRESS"
  if [ -n "$session_address" ]
  then
    echo "      well-known path $file says $session_address"
  fi
else
  if [ "$session_address" != "$DBUS_SESSION_BUS_ADDRESS" ]
  then
    echo "FAIL: mismatch between \$DBUS_SESSION_BUS_ADDRESS ($DBUS_SESSION_BUS_ADDRESS) and well-known path $file ($session_address)"
  else
    echo "PASS: match between \$DBUS_SESSION_BUS_ADDRESS ($DBUS_SESSION_BUS_ADDRESS) and well-known path $file ($session_address)"
  fi
fi

address=$(dbus-send --session --dest=org.a11y.Bus --print-reply /org/a11y/bus org.a11y.Bus.GetAddress | grep "string ")
if [ "$?" != 0 ]
then
  echo "FAIL: can't get accessibility bus from session dbus"
  address=""
else
  address=${address#   string \"}
  address=${address%\"}
  echo "PASS: got accessibility bus $address from session dbus"
fi

address2=$(xprop -root AT_SPI_BUS | grep "^AT_SPI_BUS(STRING)")
if [ "$?" != 0 ]
then
  echo "FAIL: can't get accessibility bus from root window"
  if [ -n "$address" ]
  then
    echo "WARN: you can hot-fix it by running the following command, but that will only work for the current session"
    echo "xprop -root -f AT_SPI_BUS 8s -set AT_SPI_BUS $address"
  fi
  address2=""
else
  address2=${address2#AT_SPI_BUS(STRING) = \"}
  address2=${address2%\"}
  echo "PASS: got accessibility bus $address2 from root window"
fi

if [ -n "$address" -a -n "$address2" ]
then
  if [ "$address" != "$address2" ]
  then
    echo "FAIL: accessibility bus $address from session dbus doesn't match accessibility bus $address2 from root window"
  else
    echo "PASS: accessibility buses from session dbus and from root window match"
  fi
fi

enabled=$(dbus-send --session --dest=org.a11y.Bus  --print-reply=literal /org/a11y/bus org.freedesktop.DBus.Properties.Get string:org.a11y.Status string:IsEnabled | sed -e 's/.*boolean *\([^ ]*\)/\1/')
if [ "$enabled" = true ]
then
  echo "PASS: org.a11y.Status IsEnabled is true"
else
  echo "WARN: org.a11y.Status IsEnabled is '$enabled', mozilla applications will not be accessible unless GNOME_ACCESSIBILITY is set to 1"
fi

enabled=$(dbus-send --session --dest=org.a11y.Bus  --print-reply=literal /org/a11y/bus org.freedesktop.DBus.Properties.Get string:org.a11y.Status string:ScreenReaderEnabled | sed -e 's/.*boolean *\([^ ]*\)/\1/')
if [ "$enabled" = true ]
then
  echo "PASS: org.a11y.Status ScreenReaderEnabled is true"
else
  echo "WARN: org.a11y.Status ScreenReaderEnabled is '$enabled', qt5 applications will not be accessible unless QT_LINUX_ACCESSIBILITY_ALWAYS_ON is set to 1"
fi

echo
echo Layer enabling

if type gsettings > /dev/null 2>&1
then
  enabled=$(gsettings get org.gnome.desktop.a11y.applications screen-reader-enabled)
  if [ "$enabled" != true ]
  then
    echo "WARN: screen-reader-enabled is not set in gsettings, use"
    echo "      gsettings set org.gnome.desktop.a11y.applications screen-reader-enabled true"
    echo "      to enable it"
  else
    echo "PASS: screen-reader-enabled is set in gsettings"
  fi

  enabled=$(gsettings get org.mate.interface accessibility)
  if [ "$enabled" != true ]
  then
    echo "WARN: MATE accessibility is not set in gsettings, use"
    echo "      gsettings set org.mate.interface accessibility true"
    echo "      to enable it"
  else
    echo "PASS: MATE accessibility is set in gsettings"
  fi
fi

if [ "${GTK_MODULES/*gail*/found}" != found ]
then
  echo "WARN: GTK_MODULES does not contain gail, GTK2 applications may not be accessible"
else
  echo "PASS: GTK_MODULES contains gail"
fi

if [ "${GTK_MODULES/*atk-bridge*/found}" != found ]
then
  echo "WARN: GTK_MODULES does not contain atk-bridge, GTK2 applications may not be accessible"
else
  echo "PASS: GTK_MODULES contains atk-bridge"
fi

if [ "$NO_GAIL" = 1 ]
then
  echo "FAIL: NO_GAIL is set to 1, GTK2 applications will not be accessible"
fi

if [ "$NO_AT_BRIDGE" = 1 ]
then
  echo "FAIL: NO_AT_BRIDGE is set to 1, GTK2 applications will not be accessible"
fi

if [ "$QT_ACCESSIBILITY" != 1 ]
then
  echo "WARN: QT_ACCESSIBILITY is not set to 1, Qt4 applications may not be accessible"
else
  echo "PASS: QT_ACCESSIBILITY is set to 1"
fi

if [ "$JAVA_ASSISTIVE" = OFF ]
then
  echo "FAIL: JAVA_ASSISTIVE is set to OFF, Java Swing applications will not be accessible"
fi

if [ "$GNOME_ACCESSIBILITY" != 1 ]
then
  echo "WARN: GNOME_ACCESSIBILITY is set to '$GNOME_ACCESSIBILITY', mozilla applications will not be accessible unless IsEnabled is set to true (as typically set by starting orca, but not accerciser etc.)"
fi

if [ "$ACCESSIBILITY_ENABLED" != 1 ]
then
  echo "WARN: ACCESSIBILITY_ENABLED is set to '$ACCESSIBILITY_ENABLED', chrome applications will not be accessible"
fi

for i in $(seq 7 19)
do
  if test_package openjdk-$i-jre-headless
  then
    if ! grep ^assistive_technologies=org.GNOME.Accessibility.AtkWrapper /etc/java-$i-openjdk/accessibility.properties > /dev/null 2>&1
    then
      echo "WARN: assistive technology not enabled in /etc/java-$i-openjdk/accessibility.properties, Java $i Swing applications may not be accessible."
    else
      echo "PASS: assistive technology enabled in /etc/java-$i-openjdk/accessibility.properties."
    fi
    if ! grep ^swing.defaultlaf=com.sun.java.swing.plaf.gtk.GTKLookAndFeel /etc/java-$i-openjdk/swing.properties > /dev/null 2>&1
    then
      echo "WARN: default Look and Feel is not GTK in /etc/java-$i-openjdk/swing.properties, Java $i Swing applications may not be accessible."
    else
      echo "PASS: default Look and Feel is GTK in /etc/java-$i-openjdk/swing.properties."
    fi
  fi
done
