#!/bin/bash

set -e
[ -z "$PLYMOUTH_DATADIR" ] && PLYMOUTH_DATADIR="/usr/share"
[ -z "$PLYMOUTH_CONFDIR" ] && PLYMOUTH_CONFDIR="/etc/plymouth/"
[ -z "$PLYMOUTH_POLICYDIR" ] && PLYMOUTH_POLICYDIR="/usr/share/plymouth/"
[ -z "$PLYMOUTH_CONFFILE"] && PLYMOUTH_CONFFILE="$PLYMOUTH_CONFDIR/plymouthd.conf"
[ -z "$PLYMOUTH_DEFFILE"] && PLYMOUTH_DEFFILE="/usr/share/plymouth/plymouthd.defaults"
[ -z "$OS" ] && OS=`cat /etc/os-release |grep ^NAME= |cut -d'=' -f2 |cut -d'"' -f2`

if [ -z "$PLYMOUTH_LIBEXECDIR" ]; then
        if [ -x "/usr/lib/plymouth/plymouth-update-initrd" ]; then
                 PLYMOUTH_LIBEXECDIR="/usr/lib";

        elif [ -x "/usr/libexec/plymouth/plymouth-update-initrd" ]; then
                 PLYMOUTH_LIBEXECDIR="/usr/libexec";
        fi
fi

if [ -z "$PLYMOUTH_PLUGIN_PATH" ]; then
    if [ -z "$LIB" ]; then
        PLYMOUTH_PLUGIN_PATH="$(plymouth --get-splash-plugin-path)"
    else
        [ -z "$PLYMOUTH_LIBDIR" ] && PLYMOUTH_LIBDIR="/usr/lib64"
        PLYMOUTH_PLUGIN_PATH=${PLYMOUTH_LIBDIR}/plymouth/
    fi
fi

function usage ()
{
  echo "usage: plymouth-set-default-theme { --list | --reset | <theme-name> [ --rebuild-initrd ] | --help }"
}

function show_help() {
  cat <<EOF
Plymouth theme chooser
$(usage)

  -h, --help             Show this help message
  -l, --list             Show available themes
  -r. --reset            Reset to default theme
  -R, --rebuild-initrd   Rebuild initrd (necessary after changing theme)
  <theme-name>           Name of new theme to use (see --list for available themes)

EOF
}

function list_themes ()
{
        for theme in ${PLYMOUTH_DATADIR}/plymouth/themes/*/*.plymouth; do
                [ -f $theme ] || continue;
                echo "$(basename "$theme" .plymouth)"
        done
}

function read_theme_name_from_file ()
{
        echo $(grep -v '^#' $1 2> /dev/null |
               awk '
                     BEGIN {
                        RS="[[][[:blank:]]*[^[:space:]]+[:blank:]*[]\n]";
                        FS="[=[:space:]]+";
                        OFS="";
                        ORS=""
                     }
                     $1 ~/Theme/ { print $2 }
               ')
}

function get_current_theme ()
{
        if [ -z "$THEME_NAME" -a -r "$PLYMOUTH_CONFFILE" ]; then
                THEME_NAME=$(read_theme_name_from_file $PLYMOUTH_CONFFILE)
	fi

        if [ -z "$THEME_NAME" -a -r "$PLYMOUTH_DEFFILE" ]; then
                THEME_NAME=$(read_theme_name_from_file $PLYMOUTH_DEFFILE)
	fi
}

DO_RESET=0
DO_INITRD_REBUILD=0
DO_LIST=0
DO_HELP=0
THEME_NAME=""

while [ $# -gt 0 ]; do
        case "$1" in

        -l|--list)
                if [ -n "$THEME_NAME" ]; then
                        echo "You can only specify --list or a theme name, not both" >&2
                        echo $(usage) >&2
                        exit 1
                fi

                if [ $DO_RESET -ne 0 ]; then
                        echo "You can only specify --reset or --list, not both" >&2
                        echo $(usage) >&2
                        exit 1
                fi

                DO_LIST=1
        ;;

        -R|--rebuild-initrd)
                DO_INITRD_REBUILD=1
        ;;

        -r|--reset|default)
                if [ -n "$THEME_NAME" ]; then
                        echo "You can only specify --reset or a theme name, not both" >&2
                        echo $(usage) >&2
                        exit 1
                fi

                if [ $DO_LIST -ne 0 ]; then
                        echo "You can only specify --reset or --list, not both" >&2
                        echo $(usage) >&2
                        exit 1
                fi

                DO_RESET=1
        ;;

        -h|--help)
                DO_HELP=1
        ;;

        *)
                if [ -n "$THEME_NAME" ]; then
                        echo "You can only specify one theme at a time" >&2
                        echo $(usage) >&2
                        exit 1
                fi

                if [ $DO_RESET -ne 0 ]; then
                        echo "You can only specify --reset or a theme name, not both" >&2
                        echo $(usage) >&2
                        exit 1
                fi

                if [ $DO_LIST -ne 0 ]; then
                        echo "You can only specify --list or a theme name, not both" >&2
                        echo $(usage) >&2
                        exit 1
                fi

                THEME_NAME="$1"
        ;;
  esac
  shift
done

if [ $DO_HELP -eq 1 ]; then
        show_help
        exit $?
fi

if [ $DO_LIST -ne 0 ]; then
        list_themes
        exit $?
fi

if [ $DO_RESET -eq 0 ] && [ $DO_INITRD_REBUILD -eq 0 ] && [ -z $THEME_NAME ]; then
	get_current_theme
	if [[ ! -z $THEME_NAME ]];then
	       echo $THEME_NAME;
               exit 0;
        else
		echo "No theme set."
                exit 1;
	fi
fi

if [ `id -u` -ne 0 ]; then
        echo "This program must be run as root" >&2
        exit 1

elif [ $DO_RESET -ne 0 ]; then
        if [[ -z "$RELEASE_THEME_NAME" ]] && [[ "$OS" == "SLED" ]] || [[ "$OS" == "SLES" ]] ; then
                RELEASE_THEME_NAME="SLE";

        elif [[ -z "$RELEASE_THEME_NAME" ]] && [[ "$OS" == *"openSUSE Tumbleweed"* ]] ; then
                RELEASE_THEME_NAME="bgrt";

        elif [[ -z "$RELEASE_THEME_NAME" ]] && [[ "$OS" == *"openSUSE Leap"* ]] ; then
                RELEASE_THEME_NAME="opensuse";
        fi

        Daemon_found=-1;
        Theme_found=-1;
        ShowDelay_found=-1;
        DeviceTimeout_found=-1;

        if [[ -e $PLYMOUTH_CONFFILE ]]; then
                mapfile array_config < $PLYMOUTH_CONFFILE && > plymouthd.conf
                lines=${#array_config[@]};
                line=0;
                re_daemon_head="^[[:blank:]]*\[Daemon\].*$"
                re_daemon_end="^[[:blank:]]*\[.*\]"

                for ((line=0; line<lines; line++)) do
                        if [[ ${array_config[$line]} =~ $re_daemon_head ]]; then
                                in_daemon=1;
                                Daemon_found=$line;
                        elif [[ ${array_config[$line]} =~ $re_daemon_end ]]; then
                                in_daemon=-1;
                        elif [[ $in_daemon -gt 0 ]]; then
                                if [[ ${array_config[$line]} == *"Theme="* ]]; then
                                        array_config[$line]="Theme=$RELEASE_THEME_NAME";
                                        Theme_found=$line;
                                fi

                                if [[ ${array_config[$line]} == *"ShowDelay="* ]]; then
                                        array_config[$line]="ShowDelay=0";
                                        ShowDelay_found=$line;
                                fi

                                if [[ ${array_config[$line]} == *"DeviceTimeout="* ]]; then
                                        array_config[$line]="DeviceTimeout=8";
                                        DeviceTimeout_found=$line;
                                fi
                        fi
                done
        else
                if  [[ ! -d $PLYMOUTH_CONFDIR ]]; then
                        mkdir $PLYMOUTH_CONFDIR
                fi
                touch $PLYMOUTH_CONFFILE
        fi

        if [[ Daemon_found -eq -1  ]]; then
                Daemon_found=${#array_config[@]};
                array_config+=("[Daemon]");
        fi

        if [[ Theme_found -lt 0 ]]; then
                Theme_found=Daemon_found+1;
                array_config=( "${array_config[@]:0:$Daemon_found+1}" "Theme=$RELEASE_THEME_NAME" "${array_config[@]:$Daemon_found+1}" )
        fi

        if [[ ShowDelay_found -lt 0  ]]; then
                ShowDelay_found=Theme_found+1;
                array_config=( "${array_config[@]:0:$Theme_found+1}" "ShowDelay=0" "${array_config[@]:$Theme_found+1}" )
        fi

        if [[ DeviceTimeout_found -lt 0  ]]; then
                DeviceTimeout_found=ShowDelay_found+1;
                array_config=( "${array_config[@]:0:$ShowDelay_found+1}" "DeviceTimeout=8" "${array_config[@]:$ShowDelay_found+1}" )
        fi
        printf "%s\n" ${array_config[@]} > $PLYMOUTH_CONFFILE;
	exit 0;

elif [ $DO_INITRD_REBUILD -ne 0 ]; then
        if [[ -z "$THEME_NAME" ]] ; then
                get_current_theme
        fi

        if [ ! -e ${PLYMOUTH_DATADIR}/plymouth/themes/${THEME_NAME}/${THEME_NAME}.plymouth ]; then
                echo "Failed: ${PLYMOUTH_DATADIR}/plymouth/themes/${THEME_NAME}/${THEME_NAME}.plymouth does not exist" >&2
                exit 1
        fi

        MODULE_NAME=$(grep "ModuleName *= *" ${PLYMOUTH_DATADIR}/plymouth/themes/${THEME_NAME}/${THEME_NAME}.plymouth | sed 's/ModuleName *= *//')
        if [ ! -e ${PLYMOUTH_PLUGIN_PATH}${MODULE_NAME}.so ]; then
                echo "Failed: ${PLYMOUTH_PLUGIN_PATH}${MODULE_NAME}.so does not exist" >&2
                exit 1
        fi

        [ -L ${PLYMOUTH_DATADIR}/plymouth/themes/default.plymouth ] && rm -f ${PLYMOUTH_DATADIR}/plymouth/themes/default.plymouth
        (${PLYMOUTH_LIBEXECDIR}/plymouth/plymouth-update-initrd)
        exit 0
fi
