#!/bin/bash -e
# Copyright (C) 2016 Endless Mobile, Inc.
# Licensed under the GPLv2

USERID=$(id -u)
if [ "$USERID" != "0" ]; then
    echo "Program requires superuser privileges"
    exit 1
fi

DEB_ARCH=`dpkg --print-architecture`
case ${DEB_ARCH} in
    amd64) ;; # Only 64-bit Intel architectures are supported
    *) echo "Unsupported architecture ${DEB_ARCH}"
       exit 1
       ;;
esac

TEMP_DIR=`mktemp -d`
FLASH_TEMP_DIR="${TEMP_DIR}/flash"
WIDEVINE_TEMP_DIR="${TEMP_DIR}/widevine"
mkdir -p "${FLASH_TEMP_DIR}" "${WIDEVINE_TEMP_DIR}"

DEST_DIR=/var/lib/chromium-plugins-extra/eos-chrome-plugin-updater
WGET_COMMAND="wget -c --tries=5"
DAYS_CHECK=7

# Data needed for the Flash plugin, from Adobe
FLASH_LKGV_FILE_URL="https://s3-us-west-2.amazonaws.com/abacadaba/flashplugin-$(arch).lkgv"
FLASH_LKGV_VERSION=
FLASH_LKGV_URL=
FLASH_LKGV_SHA256SUM=
FLASH_LKGV_FILENAME=

FLASH_VERSION=
FLASH_SO_FILE=libpepflashplayer.so
FLASH_VERSION_FILE=${DEST_DIR}/Flash_VERSION.txt

# Data needed for the Widevine plugin, from Google
WIDEVINE_BASE_URL=https://dl.google.com/widevine-cdm
WIDEVINE_VERSION_URL=${WIDEVINE_BASE_URL}/versions.txt
WIDEVINE_VERSION_CURRENT=
WIDEVINE_URL=
WIDEVINE_FILENAME=

WIDEVINE_VERSION=
WIDEVINE_SO_FILE=libwidevinecdm.so
WIDEVINE_TARGET_SO_FILE=libwidevinecdm.so
WIDEVINE_MANIFEST_FILE=manifest.json
WIDEVINE_TARGET_MANIFEST_FILE=Widevine_manifest.json
WIDEVINE_VERSION_FILE=${DEST_DIR}/Widevine_VERSION.txt
WIDEVINE_OLD_VERSION_FILE=${DEST_DIR}/VERSION.txt

fp_init() {
    mkdir -p ${DEST_DIR}
}

fp_exit() {
   echo $1
   rm -fr ${TEMP_DIR}
   exit 0
}

fp_refresh_version_file() {
    local version_file="$1"
    if [ ! -f ${version_file} ]; then
        echo "Version file ${version_file} does not exist. Nothing to refresh"
        return
    fi

    if [ ! -s ${version_file} ]; then
        echo "Version file ${version_file} is invalid (empty). Removing..."
        rm -f ${version_file}
        return;
    fi

    echo "Refreshing version file ${version_file}..."
    touch ${version_file}
}

fp_should_check_updates_flash() {
    local should_check_updates=true

    FLASH_VERSION="not installed"
    if [ -f ${FLASH_VERSION_FILE} ] ; then
        local current_version="$(cat ${FLASH_VERSION_FILE})"
        local target_plugin="${DEST_DIR}/$(basename ${FLASH_SO_FILE})"

        # Make sure that the current version stored is valid AND that the actual
        # plugin file is also a valid object file before giving up on checking.
        if [ -z "${current_version}" ] || ! nm ${target_plugin} > /dev/null 2>&1; then
            # No point on keeping these files in this case
            echo "Invalid version of the Flash plugin found. Removing..."
            rm -f ${FLASH_VERSION_FILE} ${target_plugin}
        else
            # If reached, we know we have a valid version file
            FLASH_VERSION=${current_version}
            if ! [ `find ${FLASH_VERSION_FILE} -daystart -mtime +${DAYS_CHECK}` ] && \
               ! [ `find ${FLASH_VERSION_FILE} -newermt "0 days"` ] ; then
                # It has been checked recently so nothing to do for now
                should_check_updates=false
            fi
        fi
    fi

    if ! ${should_check_updates}; then
        echo "No need to check the Flash plugin yet (version: ${FLASH_VERSION})"
        return 1;
    fi

    echo "Flash plugin is not installed or might be too old. Checking for a new version"
    return 0
}

fp_should_check_updates_widevine() {
    local should_check_updates=true

    # Migrate the old VERSION.txt file if present AND is not empty
    if [ -s ${WIDEVINE_OLD_VERSION_FILE} ]; then
        mv ${WIDEVINE_OLD_VERSION_FILE} ${WIDEVINE_VERSION_FILE}
    else
        # Make sure an empty file gets removed
        rm -f ${WIDEVINE_OLD_VERSION_FILE}
    fi

    WIDEVINE_VERSION="not installed"
    if [ -f ${WIDEVINE_VERSION_FILE} ] ; then
        local current_version="$(cat ${WIDEVINE_VERSION_FILE})"
        local target_plugin="${DEST_DIR}/${WIDEVINE_TARGET_SO_FILE}"
        local target_manifest="${DEST_DIR}/${WIDEVINE_TARGET_MANIFEST_FILE}"

        # Make sure that the current version stored is valid AND that the
        # actual plugin file and manifest is also on disk before giving up on checking.
        if [ -z "${current_version}" ] || \
           [ ! -f ${target_manifest} ] || \
           ! nm ${target_plugin} > /dev/null 2>&1; then
            # No point on keeping these files in this case
            echo "Invalid version of the Widevine plugin found. Removing..."
            rm -f ${WIDEVINE_VERSION_FILE} ${target_plugin}
        else
            # If reached, we know we have a valid version file
            WIDEVINE_VERSION=${current_version}
            if ! [ `find ${WIDEVINE_VERSION_FILE} -daystart -mtime +${DAYS_CHECK}` ] && \
               ! [ `find ${WIDEVINE_VERSION_FILE} -newermt "0 days"` ] ; then
                # It has been checked recently so nothing to do for now
                should_check_updates=false
            fi
        fi
    fi

    if ! ${should_check_updates}; then
        echo "No need to check the Widevine plugin yet (version: ${WIDEVINE_VERSION})"
        return 1;
    fi

    echo "Widevine plugin is not installed or might be too old. Checking for a new version"
    return 0
}

fp_fetch_flash_metadata() {
    local filename=$(basename ${FLASH_LKGV_FILE_URL})
    if ${WGET_COMMAND} "${FLASH_LKGV_FILE_URL}" -O "${FLASH_TEMP_DIR}/${filename}"; then
        while IFS='=' read key value; do
            case "$key" in
                "VERSION") FLASH_LKGV_VERSION="$value" ;;
                "URL") FLASH_LKGV_URL="$value" ;;
                "SHA256SUM") FLASH_LKGV_SHA256SUM="$value" ;;
                *) ;;
            esac
        done < ${FLASH_TEMP_DIR}/${filename}
    else
        echo "Failed to retrieve the last known good version of the Flash plugin"
        return 1
    fi

    # This will be needed then downloading and installing
    FLASH_LKGV_FILENAME=$(basename ${FLASH_LKGV_URL})
}

fp_fetch_widevine_metadata() {
    local filename=$(basename ${WIDEVINE_VERSION_URL})
    if ! ${WGET_COMMAND} "${WIDEVINE_VERSION_URL}" -O "${WIDEVINE_TEMP_DIR}/${filename}"; then
        echo "Failed to download current Widevine version"
        return 1
    fi

    WIDEVINE_VERSION_CURRENT=$(tail -n1 ${WIDEVINE_TEMP_DIR}/${filename})
    WIDEVINE_URL=${WIDEVINE_BASE_URL}/${WIDEVINE_VERSION_CURRENT}-linux-x64.zip
    WIDEVINE_FILENAME=$(basename ${WIDEVINE_URL})
}

fp_should_update_flash() {
    if fp_fetch_flash_metadata; then
       if [ "${FLASH_VERSION}" = "${FLASH_LKGV_VERSION}" ] ; then
           # Refresh the VERSION so it is not checked again until ${DAYS_CHECK} passed
           echo "Flash plugin is up-to-date"
           fp_refresh_version_file ${FLASH_VERSION_FILE}
           return 1
       else
           echo "A new version of Flash is available: ${FLASH_LKGV_VERSION} (Current: ${FLASH_VERSION})"
           return 0
       fi
    else
        echo "An error happened fetching metadata for the the Flash plugin"
        return 1
    fi
}

fp_should_update_widevine() {
    if fp_fetch_widevine_metadata; then
       if [ "${WIDEVINE_VERSION}" = "${WIDEVINE_VERSION_CURRENT}" ] ; then
           # Refresh the VERSION so it is not checked again until ${DAYS_CHECK} passed
           echo "Widevine plugin is up-to-date"
           fp_refresh_version_file ${WIDEVINE_VERSION_FILE}
           return 1
       else
           echo "A new version of widevine is available: ${WIDEVINE_VERSION_CURRENT} (Current: ${WIDEVINE_VERSION})"
           return 0
       fi
    else
        echo "An error happened fetching metadata for the Widevine plugin"
        return 1
    fi
}

fp_download_widevine() {
    echo "Downloading ${WIDEVINE_FILENAME}"
    if ! ${WGET_COMMAND} "${WIDEVINE_URL}" -O "${WIDEVINE_TEMP_DIR}/${WIDEVINE_FILENAME}"; then
        echo "Failed to download ${WIDEVINE_FILENAME}"
        return 1
    fi

    return 0
}

fp_download_adobe_flash() {
    # Get the Adobe Flash Plugin
    echo "Downloading ${FLASH_LKGV_FILENAME}"
    if ! ${WGET_COMMAND} "${FLASH_LKGV_URL}" -O "${FLASH_TEMP_DIR}/${FLASH_LKGV_FILENAME}"; then
        echo "Failed to download ${FLASH_LKGV_URL}"
        return 1
    fi

    # Verify SHA256 checksum of debian file
    echo "Verifying ${FLASH_TEMP_DIR}/${FLASH_LKGV_FILENAME}"
    echo "${FLASH_LKGV_SHA256SUM} ${FLASH_TEMP_DIR}/${FLASH_LKGV_FILENAME}" | sha256sum -c > /dev/null 2>&1 || \
    {
        echo "sha256sum mismatch ${FLASH_TEMP_DIR}/${FLASH_LKGV_FILENAME}"
        return 1
    }
}

fp_install_flash_plugin() {
    echo "Installing ${FLASH_TEMP_DIR}/${FLASH_LKGV_FILENAME}"
    if ! tar zxv -C ${FLASH_TEMP_DIR} -f ${FLASH_TEMP_DIR}/${FLASH_LKGV_FILENAME} ; then
        echo "Cannot extract files from ${FLASH_LKGV_FILENAME}"
    elif ! [ -f ${FLASH_TEMP_DIR}/${FLASH_SO_FILE} ]; then
        echo "Could not find ${FLASH_SO_FILE}"
    elif ! install -m 644 ${FLASH_TEMP_DIR}/${FLASH_SO_FILE} ${DEST_DIR} ; then
        echo "Could not copy ${FLASH_SO_FILE} into ${DEST_DIR}"
    else
        # Sanity check: don't ever write a VERSION file with an empty value
        if [ -n "${FLASH_LKGV_VERSION}" ]; then
            echo -n "${FLASH_LKGV_VERSION}" > ${FLASH_VERSION_FILE}
        fi
        echo "Flash plugin installed"
        return
    fi

    echo "Flash plugin could NOT be installed"
}

fp_install_widevine_plugin() {
    echo "Installing ${WIDEVINE_TEMP_DIR}/${WIDEVINE_FILENAME}"
    if ! unzip -d ${WIDEVINE_TEMP_DIR} ${WIDEVINE_TEMP_DIR}/${WIDEVINE_FILENAME} ; then
        echo "Cannot unpack zip file ${WIDEVINE_FILENAME}"
    elif ! [ -f ${WIDEVINE_TEMP_DIR}/${WIDEVINE_SO_FILE} ]; then
        echo "Could not find ${WIDEVINE_SO_FILE}"
    elif ! [ -f ${WIDEVINE_TEMP_DIR}/${WIDEVINE_MANIFEST_FILE} ]; then
        echo "Could not find ${WIDEVINE_MANIFEST_FILE}"
    elif ! install -m 644 ${WIDEVINE_TEMP_DIR}/${WIDEVINE_SO_FILE} ${DEST_DIR}/${WIDEVINE_TARGET_SO_FILE} ; then
        echo "Could not copy ${WIDEVINE_SO_FILE} into ${DEST_DIR}/${WIDEVINE_TARGET_SO_FILE}"
    elif ! install -m 644 ${WIDEVINE_TEMP_DIR}/${WIDEVINE_MANIFEST_FILE} ${DEST_DIR}/${WIDEVINE_TARGET_MANIFEST_FILE} ; then
        echo "Could not copy ${WIDEVINE_MANIFEST_FILE} into ${DEST_DIR}/${WIDEVINE_TARGET_MANIFEST_FILE}"
    else
        # Sanity check: don't ever write a VERSION file with an empty value
        if [ -n "${WIDEVINE_VERSION_CURRENT}" ]; then
            echo -n "${WIDEVINE_VERSION_CURRENT}" > ${WIDEVINE_VERSION_FILE}
        fi
        echo "Widevine plugin installed"
        return
    fi

    echo "Widevine plugin could NOT be installed"
}

fp_init

# Flash plugin
if fp_should_check_updates_flash ; then
    if fp_should_update_flash && fp_download_adobe_flash; then
        fp_install_flash_plugin
    else
        echo "The Flash plugin was NOT updated"
    fi
fi

# Widevine plugin
if fp_should_check_updates_widevine ; then
    if fp_should_update_widevine && fp_download_widevine; then
        fp_install_widevine_plugin
    else
        echo "The Widevine plugin was NOT updated"
    fi
fi

fp_exit "All done"

# vim: ts=2 sw=2