#!/bin/bash
### BEGIN INIT INFO
# Provides:          eliveinstalledsystem
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Should-Start:      network-manager console-setup dbus urfkill vboxweb virtualbox smartmontools cups cups-browsed inetd networking network $local_fs $syslog inetd keymap udev fail2ban
# Should-Stop:
# X-Start-Before:    lightdm entrance slim graphical getty getty.target getty@tty1.service enlightenment
# X-Stop-After:
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# X-Interactive:     true
# Short-Description: Configure Elive Installer
# Description:       This file should be used to construct scripts to be
#                    placed in /etc/init.d.
### END INIT INFO
# Policy Info:  http://wiki.debian.org/LSBInitScripts
# also check /etc/init.d/skeleton

# Author: Thanatermesis


# Defaults
#PIDDIR=/var/run/eliveinstalledsystem
#eliveinstalledsystemPID=$PIDDIR/eliveinstalledsystem.pid
DESC="Configure Elive Installer"
SCRIPTNAME=/etc/init.d/eliveinstalledsystem


# Reads config file (will override defaults above)
[ -r /etc/default/eliveinstalledsystem ] && . /etc/default/eliveinstalledsystem

. /lib/lsb/init-functions

# required for el_elive_version_get
source /usr/lib/elive-tools/functions

set +e

# systemd or sysvinit?
if pidof -cq systemd ; then
    is_systemd=1
else
    if ! [[ -e "/var/lib/dpkg/info/sysvinit-core.list" ]] ; then
        is_systemd=1
    fi
fi


do_start(){
    local _CMDLINE
    _CMDLINE="$(cat /proc/cmdline)"
    #if ! echo "${_CMDLINE}" | grep -qsE "(boot=live)"
    #then
        #exit 0
    #fi
    if echo "${_CMDLINE}" | grep -q debug ; then
        set -x
    fi

    # ignore everything in live mode
    if echo "${_CMDLINE}" | grep -q "boot=live" ; then
        return 0
    fi
    # oly if we are bash (not sh)
    #source /usr/lib/elive-tools/functions

    # make sure that the working console reads and outputs things correctly (otherwise tab not works on dialog's unless we do a "login" or "getty")
    #exec 0</dev/console 1>/dev/console 2>&1


    log_daemon_msg "Elive Installer"

    # Make sure we have our PIDDIR, even if it's on a tmpfs
    #install -o root -g root -m 755 -d $PIDDIR

    #log_progress_msg "daemonizing"

    #if ! start-stop-daemon --start --quiet --background --make-pidfile --pidfile $eliveinstalledsystemPID --oknodo --exec /usr/sbin/eliveinstalledsystemd -- -D
    #then
        #log_end_msg 1
        #exit 1
    #fi

    # ignore if we are installing the package or any apt task, we should only run this from from boot
    if ps aux | grep -vE "(grep|dpkg-old)" | grep -qsE "bin/(apt-get|aptitude|dpkg)" ; then
        return 0
    fi

    set +e


    if [[ -s "/etc/elive/installation-status" ]] ; then
        # if we are here is because the installer finished (but not booted yet)
        var="$( grep "Status: " "/etc/elive/installation-status" | grep Status | sed -e 's|^.*Status: ||g' | tail -1 )"

        #
        # POST-INSTALL hooks:
        #
        if [[ "${var}" = "dumped" ]] ; then
            echo "Please wait, Elive is finishing to configure your system..."
            echo "Please wait, Elive is finishing to configure your system..." 1>&2

            # print message in all consoles too:
            for i in $(seq 5) ; do
                echo -e "\n\n
***************************************************************
 Please wait, Elive is finishing to Configure your System...
 Your computer will reboot when finish.
***************************************************************
" > /dev/tty${i}
            done
            sleep 1

            el_info "Please wait, Elive is finishing to configure your system..."
            log_progress_msg "optimizing system"

            # just to make sure
            unset DEBIAN_FRONTEND


            # remove old upgrade dirs
            if [[ -d "/upgrade" ]] ; then
                log_progress_msg "Removing old Elive temporal Live System"
                rm -rf /upgrade 2>/dev/null || true
            fi

            # creates /etc printer configurations:
            if dpkg -l | grep -qsE "cups-(pdf|driver-gutenprint)" ; then
                log_progress_msg "reconfiguring printers"
                if ! timeout 620 dpkg-reconfigure -fnoninteractive "cups-pdf" 1>/dev/null 2>&1 ; then
                    log_progress_msg "failed to reconfigure printers"
                    true
                fi
            fi

            # reconfigure needed packages:
            # setcap issues (ping from user, etc):
            if dpkg -l | grep -qsE "iputils-ping" ; then
                log_progress_msg "reconfiguring iputils"
                chmod u+s /bin/ping 2>/dev/null || true
                if ! timeout 620 dpkg-reconfigure -fnoninteractive "iputils-ping" 1>/dev/null 2>&1 ; then
                    log_progress_msg "failed to reconfigure iputils-ping"
                    true
                fi
            fi

            for i in $( grep -El "\W+setcap\W+" /var/lib/dpkg/info/*postinst | sed -e 's|\:.*$||g' -e 's|\.postinst||g' -e 's|^.*/||g' )
            do
                for j in /var/lib/dpkg/info/${i}.list /var/lib/dpkg/info/${i}:*.list
                do
                    if [[ -f "$j" ]] ; then
                        j="${j##*/}"
                        j="${j%.list}"
                        log_progress_msg "reconfiguring $j"
                        if ! timeout 620 dpkg-reconfigure -fnoninteractive "$j" 1>/dev/null 2>&1 ; then
                            log_progress_msg "failed to reconfigure '$j'"
                            true
                        fi
                    fi
                done
            done


            # update grub, always, partitions could hvae changed and we want a default settings (not the ones generated in live)
            log_progress_msg "Updating GRUB"

            # temporal fix:
            if ! grep -qsi "^GRUB_DISABLE_OS_PROBER=.*false" "/etc/default/grub" ; then
                el_error "GRUB_DISABLE_OS_PROBER entry not found: $( grep GRUB_DISABLE_OS_PROBER "/etc/default/grub" )"
                sed -i -e '/^GRUB_DISABLE_OS_PROBER=/d' "/etc/default/grub"
                echo -e "# allow other operating systems appear in your boot menu\nGRUB_DISABLE_OS_PROBER=\"false\"" >> "/etc/default/grub"
            fi

            if timeout 3000 update-grub ; then
                log_progress_msg "GRUB updated"
            else
                log_progress_msg "FAILED to update GRUB"
                sleep 2
                true
            fi

            # grub-like for macs
            #if which refind-install 2>/dev/null ; then
                #refind-install
            #fi

            # disable unneeded services
            if ((is_systemd)) ; then
                if LC_ALL=C LESS="" PAGER="" COLUMNS="200" systemctl status vboxweb | colors-remove | grep -qs ": failed " ; then
                    LC_ALL=C LESS="" PAGER="" COLUMNS="200" systemctl disable vboxweb || true
                fi
                if LC_ALL=C LESS="" PAGER="" COLUMNS="200" systemctl status urfkill | colors-remove | grep -qs ": failed " ; then
                    LC_ALL=C LESS="" PAGER="" COLUMNS="200" systemctl disable urfkill || true
                fi
                if LC_ALL=C LESS="" PAGER="" COLUMNS="200" systemctl status console-setup | colors-remove | grep -qs ": failed " ; then
                    LC_ALL=C LESS="" PAGER="" COLUMNS="200" systemctl disable console-setup || true
                fi
            fi

            # flush
            sync

            # disable other ones and report them too
            if ((is_systemd)) ; then
                while read -ru 3 unit
                do
                    if [[ -n "$unit" ]] ; then
                        unit="$( echo "$unit" | tr ' ' '\n' | tr '\t' '\n' | grep "\.service$" | sed -e 's|\.service||g' )"

                        case "$unit" in
                            vboxweb|urfkill|console-setup)
                                # already disabled
                                true
                                ;;
                            systemd-modules-load|fail2ban|NetworkManager-wait-online)
                                # good ones
                                true
                                ;;
                            smartd)
                                # whitelisted ones to disable
                                LC_ALL=C LESS="" PAGER="" COLUMNS="200" systemctl disable "$unit" || true
                                packages_to_remove="$packages_to_remove smartmontools"
                                ;;
                            acer-aspireone-fand)
                                # whitelisted ones to disable
                                LC_ALL=C LESS="" PAGER="" COLUMNS="200" systemctl disable "$unit" || true
                                packages_to_remove="$packages_to_remove acer-aspireone-fand"
                                ;;
                            hdapsd)
                                # whitelisted ones to disable
                                LC_ALL=C LESS="" PAGER="" COLUMNS="200" systemctl disable "$unit" || true
                                packages_to_remove="$packages_to_remove hdapsd"
                                ;;
                        esac
                    fi
                done 3<<< "$( COLUMNS="200" LC_ALL=C LESS="" PAGER="" systemctl list-units | grep "^\*.* failed " )"


                log_progress_msg "Checking systemd units"

                # systemd remaining broken units to check
                while read -ru 3 unit
                do
                    if [[ -n "$unit" ]] ; then
                        unit="$( echo "$unit" | tr ' ' '\n' | tr '\t' '\n' | grep "\.service$" | sed -e 's|\.service||g' )"

                        case "$unit" in
                            *)
                                if [[ -n "$unit" ]] ; then
                                    el_warning "UNIT failed: '$unit', disable it?"
                                    # temporally disabled, we don't want to disable what we don't know, for example systemd-modules-load should be never be disabled
                                fi
                                ;;
                        esac
                    fi
                done 3<<< "$( COLUMNS="200" LC_ALL=C LESS="" PAGER="" systemctl list-units | grep "^\*.* failed " )"
            fi

            log_progress_msg "Creating unique machine-id"

            # set machine-id {{{
            # create /etc/machine-id
            if ! [[ -s "/etc/machine-id" ]] ; then
                rm -f "/var/lib/dbus/machine-id" "/etc/machine-id"
                systemd-machine-id-setup 1>/dev/null 2>&1 || true
                ln -fs /etc/machine-id "/var/lib/dbus/machine-id" || true
                # update: blanking out the machine-id will generate a new one
                #: > "/etc/machine-id"
            fi
            # - set machine-id }}}

            #if ! el_verify_internet fast ; then
                #sleep 3
            #fi

            # remove some unneeded packages
            if [[ -n "$packages_to_remove" ]] ; then
                log_progress_msg "Removing unneeded packages"
                if ! TERM=linux DEBIAN_FRONTEND=noninteractive DEBIAN_PRIORITY=critical DEBCONF_NONINTERACTIVE_SEEN=true DEBCONF_NOWARNINGS=true  apt-get remove --purge -y $packages_to_remove ; then
                    log_progress_msg "failed to remove packages: $packages_to_remove"
                    true
                fi
            fi

            # fix apt
            if ! TERM=linux DEBIAN_FRONTEND=noninteractive DEBIAN_PRIORITY=critical DEBCONF_NONINTERACTIVE_SEEN=true DEBCONF_NOWARNINGS=true  apt-get -f -y install ; then
                log_progress_msg "failed to fix apt"
                true
            fi

            # reload init orders
            if ((is_systemd)) ; then
                LC_ALL=C LESS="" PAGER="" COLUMNS="200" systemctl daemon-reload || true
            fi

            # openrc faster tweaks
            if ((is_openrc)) ; then
                # silent boot, faster
                sed -i 's/^#\?rc_verbose=.*/rc_verbose="NO"/' /etc/rc.conf
                sed -i 's/^#\?rc_logger=.*/rc_logger="NO"/' /etc/rc.conf
                # Rebuild dependency trees with newer packages & defaults
                rc-update
            fi

            # change the status, so that the installer can know that the system booted correctly
            sed -i '/Status:/d' "/etc/elive/installation-status"
            echo -e "Status: configured" >> "/etc/elive/installation-status"
            sync

            log_progress_msg "Rebooting computer in 5..."
            sleep 1
            log_progress_msg "Rebooting computer in 4..."
            sleep 1
            log_progress_msg "Rebooting computer in 3..."
            sleep 1
            log_progress_msg "Rebooting computer in 2..."
            sleep 1
            log_progress_msg "Rebooting computer in 1..."
            reboot




        fi

        # first boot already made
        if [[ "${var}" = "configured" ]] ; then
            # change the status, so that the installer can know that the system booted correctly
            sed -i '/Status:/d' "/etc/elive/installation-status"
            echo -e "Status: installed" >> "/etc/elive/installation-status"


            # now, we can remove the eliveinstaller package and other "live" things
            log_progress_msg "Removing Elive Installer"
            precache "$0"

            # remove installer
            package_installer="$( LC_ALL=C dpkg -l | grep "^ii.*eliveinstaller" | awk '{print $2}' | tail -1 )"
            if [[ -n "$package_installer" ]] ; then
                TERM=linux DEBIAN_FRONTEND=noninteractive DEBIAN_PRIORITY=critical DEBCONF_NONINTERACTIVE_SEEN=true DEBCONF_NOWARNINGS=true  apt-get remove --purge -y $package_installer
            fi

            # cleanups
            TERM=linux DEBIAN_FRONTEND=noninteractive DEBIAN_PRIORITY=critical DEBCONF_NONINTERACTIVE_SEEN=true DEBCONF_NOWARNINGS=true  apt-get clean

            log_progress_msg "Done"
        fi
    fi


    # turn off debugging if we have finished
    if echo "${_CMDLINE}" | grep -q debug ; then
        set +x
    fi

    true
    log_end_msg 0
}

do_stop(){
    #log_daemon_msg "Stopping eliveinstalledsystem"
    true
    #log_progress_msg "almost"

    #start-stop-daemon --stop --quiet --pidfile $eliveinstalledsystemPID
    # Wait a little and remove stale PID file
    #if [ -f $eliveinstalledsystemPID ] && ! ps h $(cat $eliveinstalledsystemPID) > /dev/null
    #then
        ## Stale PID file (eliveinstalledsystem was succesfully stopped),
        ## remove it (should be removed by eliveinstalledsystem itself IMHO.)
    #rm -f $eliveinstalledsystemPID
    #fi


    #log_end_msg 0
}

case "$1" in
    "")
        echo "Error: eliveinstalledsystem should be called with the 'start' argument." >&2
        ;;
    start)
        do_start
        ;;
    stop)
        do_stop
        ;;
    restart|reload|force-reload)
        "$0" stop
        "$0" start
        ;;
    *)
        echo "Usage: eliveinstalledsystem [start|stop]" >&2
        exit 3
        ;;
esac

# vim: set filetype=sh :
