#!/bin/bash

#    update-bunsen-pepperflash: a script to check Adobe for
#    possible upgrades of the pepperflash plugin for Linux,
#    and offer to download and install.
#    This script is part of the package bunsen-pepperflash.
#
#    Copyright © 2016  John Crawley <john@bunsenlabs.org>
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    This program 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 General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.

set -u

HELP='A script to check Adobe for possible upgrades of the pepperflash plugin
for Linux, and offer to download and install.
Only for i386 and amd64 architectures,
and bunsen-pepperflash replaces the package pepperflashplugin-nonfree,
which must be uninstalled before use.

Chromium will be able to use the downloaded plugin immediately,
but for Mozilla browsers the package
browser-plugin-freshplayer-pepperflash must be installed.

This script is run automatically when the package bunsen-pepperflash
is installed, but may be run manually.

Options:
--help -h       Show this message.
--status -s     Show installed and upstream versions.
--install -i    Install or upgrade the plugin from Adobe,
                 if upstream version is newer.
--uninstall -u  Remove the plugin.
--upgrade -g    Upgrade the plugin, only if it is currently installed.

To use options -i, -u and -g, run script as root.

Option -g is intended for non-interactive use:
STDOUT is quieter and important messages are sent via notify-send.

NOTE: If the plugin is uninstalled with the -u option,
it will still be reinstalled after a package upgrade.
To permanently uninstall the plugin, uninstall this package.

'

pkgname=bunsen-pepperflash

flashdir="/usr/lib/$pkgname" # Flash plugin will be installed here.
filename=libpepflashplayer.so
manifest=manifest.json

flash_file="$flashdir/$filename"
manifest_file="$flashdir/$manifest"

chromium_confdir='/etc/chromium.d/'
chromium_configfile="$chromium_confdir/$pkgname"

# config file for browser-plugin-freshplayer-pepperflash
freshwrapper_configfile='/etc/freshwrapper.conf'

# script should be installed by same package
version_checker='/usr/lib/bunsen/pepperflash/get-adobe-flashver.py'

required_commands=(curl wget strings)

error_exit() {
    echo "$0 error: $1" >&2
    exit 1
}

[[ -x "$version_checker" ]] || error_exit "Cannot find necessary script: $version_checker"
[[ $(dpkg-query --show --showformat='${db:Status-Abbrev;2}' pepperflashplugin-nonfree 2>/dev/null) = ii ]] && error_exit 'pepperflashplugin-nonfree must be uninstalled before using this script.'

case "$(dpkg --print-architecture)" in
i386)
    arch='i386'
    ;;
amd64)
    arch='x86_64'
    ;;
*)
    error_exit 'There is no flash plugin available for your system architecture.'
    ;;
esac

missing_commands=()
for i in "${required_commands[@]}"
do
    hash $i || missing_commands+=("$i")
done
[[ ${#missing_commands[@]} -eq 0 ]] || error_exit "This script requires the following commands: ${missing_commands[*]}
Please install the packages containing the missing commands
and rerun the script."

opt="${1-}"
quiet=false

check_root() {
    [[ $( id -u ) -eq 0 ]] || error_exit "$opt: must be root to use this option"
}

check_versions(){
    echo 'Checking Flash version available from Adobe...'
    newver=$($version_checker) || error_exit "$version_checker returned an error."
    [[ "$newver" =~ ^[0-9]+(\.[0-9]+){3}$ ]] || error_exit "$version_checker returned an unacceptable result: $newver."
    echo "Upstream version: $newver"

    if [[ -r $flash_file ]]
    then
        instver=$(strings "$flash_file" 2>/dev/null | sed -n '/LNX/ {s/^LNX //;s/,/./gp}')
        echo "Installed version: $instver"
    else
        instver=''
        echo "There is no installed file $flash_file"
        return 0
    fi

    if dpkg --compare-versions "$newver" gt "$instver"
    then
        [[ ${quiet-} = true ]] || echo "The upstream version is newer."
        return 0
    else
        [[ ${quiet-} = true ]] || echo "You already have the newest version."
        return 1
    fi
}

cleanup(){
    [[ ${quiet-} = true ]] || echo 'Cleaning up...'
    [[ -d $tempdir && $tempdir = /tmp/* ]] && {
        rm -rf "$tempdir"
        [[ ${quiet-} = true ]] || echo "Deleted $tempdir"
        return 0
    }
    return 1
}

config_chromium(){
    [[ ${quiet-} = true ]] || echo 'Configuring chromium...'
    mkdir -p "$chromium_confdir" || error_exit "failed to make directory $chromium_confdir"
    rm -f "$chromium_confdir/pepperflashplugin-nonfree"
    cat <<EOF > "$chromium_configfile" || error_exit "failed to generate $chromium_configfile"
flashso="$flash_file"
flashversion=\$(strings \$flashso 2>/dev/null |  sed -n '/LNX/ {s/^LNX //;s/,/./gp}')
CHROMIUM_FLAGS="\$CHROMIUM_FLAGS --ppapi-flash-path=\$flashso --ppapi-flash-version=\$flashversion"

EOF
}

config_freshwrapper(){
    [[ ${quiet-} = true ]] || echo 'Configuring the freshplayer plugin...'
    cat <<< "$freshwrapper_conf" > "$freshwrapper_configfile" || error_exit "failed to generate $freshwrapper_configfile"
}

install_flash(){
    check_versions || return 0
    [[ ${quiet-} = true ]] || echo 'Installing flash...'
    tempdir="$(mktemp -d)" || error_exit 'failed to make temporary directory'
    trap cleanup EXIT
    local wget_opt=
    [[ ${quiet-} = true ]] && wget_opt='-q'
    wget ${wget_opt-} --directory-prefix="$tempdir" "https://fpdownload.adobe.com/pub/flashplayer/pdc/$newver/flash_player_ppapi_linux.$arch.tar.gz" || error_exit 'download failed'
    tar -xf "$tempdir/flash_player_ppapi_linux.$arch.tar.gz" --directory "$tempdir" "$filename" "$manifest" || error_exit 'failed to unpack archive'
    gotver=$(strings "$tempdir/$filename" 2>/dev/null | sed -n '/LNX/ {s/^LNX //;s/,/./gp}')
    [[ "$gotver" = "$newver" ]] || error_exit "The version of the downloaded flash library does not seem to match that published on the Adobe site."
    mkdir -p "$flashdir" || error_exit "failed to make directory $flashdir"
    mv -f "$tempdir/$filename" "$tempdir/$manifest" "$flashdir" || error_exit "failed to move files to $flashdir"
    config_chromium
    config_freshwrapper
    if [[ ${quiet-} = true ]] && hash bl-notify-broadcast
    then
        bl-notify-broadcast 'Flash upgrade' "The Adobe pepperflash plugin has been upgraded
from <b>$instver</b> to <b>$newver</b>" --icon=dialog-information --expire-time=20000
    fi
}

upgrade_flash(){
    [[ -r $flash_file ]] || {
        echo "Flash plugin not currently installed"
        return 0
    }
    install_flash
}

uninstall_flash(){
    echo 'Uninstalling flash...'
    rm -f "$flash_file" "$manifest_file"
    rmdir --ignore-fail-on-non-empty "$flashdir" || true
    rm -f "$chromium_configfile"
    rm -f "$freshwrapper_configfile"
}

# contents of freshwrapper.conf
freshwrapper_conf="# Configuration options for FreshPlayerPlugin

# This configuration file is optional. Wrapper will search for it first
# in ~/.config/freshwrapper.conf, then in /etc/freshwrapper.conf.
# If wrapper fails to find configuration, it will use default values,
# which you can find below

# Audio buffer is used to continuously provide sound adapter with data.
# Values too low may lead to buffer underruns and stuttering.  Values
# too high will lead to noticeable latency. Usually plugin selects size
# on its own, but you may override bounds here

# lower bound for audio buffer size, in milliseconds
audio_buffer_min_ms = 20

# higher bound of audio buffer size, in milliseconds
audio_buffer_max_ms = 500

# output sound through JACK. If enabled, only JACK will be tried, and if
# your machine doesn't have it, there would be no sound, and no sync
audio_use_jack = 0

# whenever to automatically connect application ports to system ones.
# If you set this to one, no sound would be produces until you make
# connection some way
jack_autoconnect_ports = 1

# JACK server name. Omit the option to use default value
#
# jack_server_name = \"default\"

# starts JACK server on demand
jack_autostart_server = 1

# Path to the Pepper Flash plugin.
# If the option is absent, freshwrapper will search for Pepper Flash in
# a number of locations where it could be. Usually that's enough, but if
# not, you should manually enter the right path. Multiple paths could
# be specified, separated by colon.
#pepperflash_path = \"/opt/google/chrome/PepperFlash/libpepflashplayer.so\"
########################################################################
## This line added by $0 ##
pepperflash_path = \"$flash_file\"

# \"Command-line\" arguments for Flash
flash_command_line = \"enable_hw_video_decode=1,enable_stagevideo_auto=1\"

# enable 3d and stage 3d
enable_3d = 1

# enable hardware-accelerated video decoding. Requires 3d to really work
enable_hwdec = 0

# when set to 1, limits output to warnings and errors only
quiet = 0

# When multiple monitors with different resolutions are used, size
# of fullscreen window can vary. But some Flash movies request these
# parameters once at startup and rely on them to be correct. By default,
# if zeros are used here, freshwrapper will select minimal width and
# height across all monitors.
fullscreen_width = 0
fullscreen_height = 0

# Enables DNS query case randomization to partially protect against DNS
# poisoning attacks. It was reported that some Mikrotik routers do not
# support this trick. Set parameter to 0 if you have an affected model
randomize_dns_case = 0

# scaling factor (floating point value) used to convert screen pixels
# to device independent pixels. You may need it for displays with
# high DPI
device_scale = 1

# method org.freedesktop.ScreenSaver.SimulateUserActivity() in KDE 5 seems
# to have no effect unless GetSessionIdleTime() called afterwards. Set
# parameter to 1 to call latter
quirk_plasma5_screensaver = 0

# whenever to use windowed plugin mode
enable_windowed_mode = 1

# whenever XEmbed used in windowed mode (if browser advertises its support)
enable_xembed = 1

# if set to 1, fullscreen window will be kept always above browser, and hidden
# from taskbar and pager
tie_fullscreen_window_to_browser = 1

# enable using of VA-API for hardware accelerated video decoding
enable_vaapi = 1

# enable using of VDPAU for hardware accelerated video decoding
enable_vdpau = 1

# microseconds to wait after vsync event
vsync_afterwait_us = 0

# fullscreen transition delay, in milliseconds
fs_delay_ms = 300

# wait for vertical blank event before drawing on screen
enable_vsync = 1

# how close in time two clicks should be to treat them as a doubleclick
double_click_delay_ms = 400

# show version and git commit hash (if was available) of freshwrapper
# in the context menu (right mouse button menu)
show_version_info = 0

# probe video capture devices for their names and capabilities
probe_video_capture_devices = 1

# use XRender to blend images
enable_xrender = 1
"
# end freshwrapper config

case $opt in
--help|-h)
    echo "$HELP"
    exit 0
    ;;
--install|-i)
    check_root
    install_flash
    exit
    ;;
--uninstall|-u)
    check_root
    uninstall_flash
    exit
    ;;
--upgrade|-g)
    quiet=true
    check_root
    upgrade_flash
    ;;
--status|-s)
    check_versions
    exit
    ;;
'')
    echo "$HELP"
    exit 1
    ;;
*)
    echo "$1: no such option

$HELP"
    exit 1
    ;;
esac
