#!/bin/bash
SOURCE="$0"
# fix for:  sudo -E
if [[ "$UID" = 0 ]] ; then
    export HOME="/root"
fi

source /etc/default/locale 1>/dev/null 2>&1

source /usr/lib/elive-tools/functions
el_make_environment

source /usr/share/eliveinstaller/installer_functions.sh || exit 40

source /usr/bin/gettext.sh
TEXTDOMAIN="eliveinstaller"
export TEXTDOMAIN
unset is_console

# Lock system (good one) {{{
lockfile="/tmp/.$(basename "$0")-${USER}.lock"

#exit_ok(){
    #rm -f "$lockfile"
#}
#exit_error(){
    #rm -f "$lockfile"
#}

if [[ -r "$lockfile" ]] ; then
    PROCCESS="$(cat $lockfile)"
else
    PROCCESS=" "
fi

if [[ -z "$IGNOREALREADYRUNNING" ]] && (sudo ps up $PROCCESS) 1>/dev/null 2>&1 ; then
    zenity --error --text="$( eval_gettext "The installer is already running, please wait a minute for it to close completely and do not start the installer multiple times." )" 2>/dev/null

    # check for virtualbox buggy states
    if [[ -s "/etc/elive/machine-profile" ]] ; then
        source /etc/elive/machine-profile

        if [[ "$MACHINE_VIRTUAL" = "yes" ]] ; then
            #if [[ "$MACHINE_VIRTUAL_TYPE" = "virtualbox" ]] ; then
            if [[ "$( cat /proc/cpuinfo | grep "^processor" | wc -l)" -gt 1 ]] ; then
                zenity --warning --text="$( eval_gettext "There's a possible bug in virtual machines when configured to use multiple CPUs, causing processes to run with incorrect synchronicity. Change your settings to use only one CPU and set the paravirtualization mode to KVM." )" 2>/dev/null
            fi
        fi
    fi

    exit
else
    if [[ -n "$IGNOREALREADYRUNNING" ]] ; then
        sleep 5
    fi
    echo $$ > "$lockfile"
fi

# traps needs to be after the lock verification, in order to not remove it when we are already running
#trap "exit_ok" EXIT
#trap "exit_error" 1 3 5 6 14 15 ERR TERM

# SET the lock file
echo "$$" > "$lockfile"


# end lock system }}}

check_gl_acceleration_in_new_e(){
    local dir file MACHINE_VIRTUAL value

    if [[ -e "/etc/elive/machine-profile" ]] ; then
        source /etc/elive/machine-profile
        if [[ "$MACHINE_VIRTUAL" = "yes" ]] ; then
            if [[ -n "$E_START" ]] ; then
                if [ -n "$E_START" ] && [ -z "$E_HOME_DIR" ] ; then
                    E_HOME_DIR="$HOME/.e/e17"
                fi
                # default E profile of user
                dir="${E_HOME_DIR}/config/$(enlightenment_remote -default-profile-get)"
                if [[ "$E_HOME_DIR" = "$HOME/.e/e17" ]] ; then
                    file="${dir}/module.comp.cfg"
                else
                    file="${dir}/e_comp.cfg"
                fi

                value="$( grep -F 'value "engine"' "$temp" | sed -e 's|^.*: ||g' -e 's|;.*$||g' | tail -1 )"
                case "$value" in
                    2)
                        local message_vbox
                        message_vbox="$( printf "$( eval_gettext "Hardware acceleration might crash in virtual environments. We recommend to disable GL acceleration in the Engine settings of your desktop before to continue with the installation." )" "" )"
                        zenity --warning --text="$message_vbox"

                        ;;
                esac

            fi
        fi
    fi
}

check_new_e_unstable_crash(){
    if [[ -n "$E_HOME_DIR" ]] ; then
        local message_enlightenment_unstable
        message_enlightenment_unstable="$( printf "$( eval_gettext "Currently, the new Enlightenment desktop isn't stable, so using the installer may cause crashes that can lead to incomplete or broken installations, so for now, it's best to install Elive with the E16 desktop and switch to Enlightenment later via the login manager after logging in, we are working on fixing this, and your crowdfunding support will help us do it faster." )" "" )"
        zenity --error --text="$message_enlightenment_unstable"
        exit 1
    fi
}

main(){
    # pre {{{
    local guitool logs exit_status
    guitool="/usr/bin/zenity --window-icon=/usr/share/icons/gnome/256x256/apps/logo-elive.png"

    logs="/tmp/eliveinstaller-debug-process.txt"
    rm -f "$logs"

    if [[ "$USER" = "root" ]] && [[ "$HOME" = "/home"* ]] ; then
        export HOME="/root"
    fi

    el_config_get

    # never blank screen
    # Disable screen blanking and DPMS to prevent the screen from turning off during installation
    xset s off -dpms
    xset dpms force on
    xset dpms 0 0 0

    # }}}
    # checks {{{
    check_new_e_unstable_crash
    check_gl_acceleration_in_new_e

    # - checks }}}
    #if LC_ALL=C dpkg --compare-versions "$datebuilded" "gt" "2017-02-10" && dpkg --compare-versions "$(date +%F)" "lt" "2017-09-01"  ; then
        #if LC_ALL=C dpkg --compare-versions "$eliveversion" "gt" "2.8.5" && dpkg --compare-versions "$eliveversion" "lt" "2.9.0" ; then

    # connect to internet
    # request the user to connect to internet first {{{
    # temporal file to be able to show the progress
    TMP_PROGRESS_WORKING_WAITING_f="/tmp/.installer-update"

    if el_verify_internet 2>/dev/null ; then
        guitool working_start "$( eval_gettext "Updating the installer before installation." )"

    else

        if $guitool --title='Elive Installer' --question --text="$( eval_gettext "Connect to the internet before installing Elive. The installer will be updated automatically, ensuring you will use the latest installer version with all fixes found and new improvements." )" 2>/dev/null ; then

            # restart daemon & applet
            #service network-manager restart
            #sleep 5
            if [[ "$UID" = 0 ]] ; then
                if [[ -n "$E_START" ]] ; then
                    su -c "enlightenment_remote -exec-cmd \"wifi-app\"" $eliveuser
                else
                    su -c "wifi-app" $eliveuser &
                fi
            else
                if [[ -n "$E_START" ]] ; then
                    enlightenment_remote -exec-cmd "wifi-app"
                else
                    wifi-app &
                fi
            fi

            guitool working_start "$( eval_gettext "Waiting for internet connection..." )"

            # wait a bit so the user can connect to internet
            for i in $(seq 60)
            do
                if el_verify_internet fast 2>/dev/null ; then
                    break
                else
                    sleep 2
                fi
            done


            # verify connection
            if ! el_verify_internet 2>/dev/null ; then
                if $guitool --title='Elive Installer' --question --text="$( eval_gettext "Have you successfully connected to the internet? Please close this dialogue after you have completed configuring your network settings and confirmed the connection is active." )" 2>/dev/null ; then
                    sleep 2
                fi
            fi

            # close it or we will not be able to exit the installer later, we don't need it anymore
            killall nm-applet 2>/dev/null 1>&2 || killall -9 nm-applet 2>/dev/null 1>&2 || true
        fi


        # if no internet, tell the user about missing features
        if ! el_verify_internet 2>/dev/null && ! grep -qs "country=" /proc/cmdline ; then
            local message_locale_dynamic
            message_locale_dynamic="$( eval_gettext "Tip: Elive offers a wide selection of additional languages. To enable your country's language, boot with an internet connection or add a boot parameter like 'country=uk', using your country code." )"

            # TODO: improve the live-config script to add UTF-8 if is not added, and to check in the list, etc... improve it
            $guitool --title='Elive Installer' --info --text="$message_locale_dynamic" 2>/dev/null
        fi
    fi

    # }}}
    # update installer (fast mode) {{{

    elinst_package_name="$( LC_ALL="$EL_LC_EN" COLUMNS=1000 dpkg -l | grep "^ii\s*eliveinstaller-" | awk '{print $2}' | sort -u | sed -e 's|:.*||g' | tail -1 )"

    # update the installer first
    # if enough ram or at least not previously failed
    if ! ps aux | grep -v grep | grep -qs "explode-and-start-installer" ; then

        installed="$( LC_ALL="$EL_LC_EN" apt-cache policy "$elinst_package_name" | LC_ALL=C grep "Installed:" | sed -e 's|^.*Installed: ||g' | head -1 | LC_ALL=C grep -E "^[[:digit:]]*" )"
        read -r installed <<< "$installed"

        # update installer
        NOREPORTS=1 el_package_upgrade_fast 120 force "$elinst_package_name" "elive-tools"
        # update functions always
        source /usr/lib/elive-tools/functions

        installed_new="$( LC_ALL="$EL_LC_EN" apt-cache policy "$elinst_package_name" | LC_ALL=C grep "Installed:" | sed -e 's|^.*Installed: ||g' | head -1 | LC_ALL=C grep -E "^[[:digit:]]*" )"
        read -r installed_new <<< "$installed_new"

        # notify user if has been updated
        if [[ "$installed" != "$installed_new" ]] ; then
            # play updated song
            if [[ -s "/usr/share/eliveinstaller/data/1up.wav" ]] ; then
                if [[ -x "$(which paplay || true )" ]] ; then
                    paplay "/usr/share/eliveinstaller/data/1up.wav" &
                else
                    if [[ -x "$(which aplay || true )" ]] ; then
                        aplay "/usr/share/eliveinstaller/data/1up.wav" &
                    fi
                fi
            fi
            el_notify normal logo-elive "Installer Updated" "$( eval_gettext "The installer has been updated with the latest fixes and features" )" 2>/dev/null
            export is_installer_updated=1
        fi
    fi
    guitool working_stop


    # }}}


    [[ -s /etc/elive/settings ]] && source /etc/elive/settings

    if [[ -n "$patreon_email" ]] ; then
        conf_send_debug_reports_email="$patreon_email"
    fi

    if grep -qsw "thanatests" /proc/cmdline ; then
        conf_send_debug_reports_email="thanatests-mode@gmail.com"
        conf_send_debug_reports="yes"
        is_thanatests=1
    fi

    if [[ "$conf_send_debug_reports_email" = "no-email" ]] ; then
        unset conf_send_debug_reports_email
    fi

    if [[ -z "$conf_send_debug_reports_email" ]] ; then
        conf_send_debug_reports="no"
    fi
    # update: do not enable otherwise user will be notified about the why of inserting email
    # if el_check_version_development 1>/dev/null 2>&1 ; then
    #     # ignore reports for more than X days old (2 months)
    #     if el_check_version_development_is_days_recent 60 1>/dev/null 2>&1 ; then
    #         conf_send_debug_reports="yes"
    #     fi
    # else
    #     # stable versions will need more time:
    #     if el_check_version_is_days_recent 120 1>/dev/null 2>&1 ; then
    #         conf_send_debug_reports="yes"
    #     fi
    # fi

    # previous fail, insist to add email or suggest chat {{{
    if ! echo "$conf_send_debug_reports_email" | grep -Eiqs '([[:alnum:]_.-]+@[[:alnum:]_.-]+?\.[[:alpha:].]{2,6})' ; then
        if [[ -e /tmp/.eliveinstaller-failed ]] ; then
            if [[ -x "$(which hexchat || true )" ]] ; then
                if $guitool --title='Elive Installer' --question --text="$( eval_gettext "The installation failed on a previous attempt. If you provided your email, we can assist you using your debug reports. You can also use the online chat now if you'd like to." )" 2>/dev/null ; then
                    ( hexchat & )
                fi
            else
                $guitool --title='Elive Installer' --warning --text="$( eval_gettext "The installation failed on a previous attempt. If you provide your email, we can assist you using your debug reports." )" 2>/dev/null
            fi
        fi
    fi

    # }}}

    # ask for email ID
    if [[ "$conf_send_debug_reports" != "yes" ]] && el_verify_internet "fast" ; then
        if $guitool --title='Elive Installer' --question --text="$( eval_gettext "By enabling automatic reports we can notify you of fixes for any issues you may encounter. It also helps make Elive more stable by allowing us to identify and fix errors. No personal data is sent; doing so, you're also supporting the entire community." )" 2>/dev/null ; then
            conf_send_debug_reports="yes"
        else
            conf_send_debug_reports="yes" el_mark_state "noreports" 2>/dev/null || true
            # user don't want to send reports, respect that globally
            conf_send_debug_reports="no"
        fi
    fi

    if [[ "$conf_send_debug_reports" = "yes" ]] ; then
        # 3 attempts
        local message_email
        local message_email2
        message_email="$( printf "$( eval_gettext "Provide your email for contact in case it is necessary." )" "" )"
        message_email2="$( printf "$( eval_gettext "Your email is optional and secure with us, but will be helpfull if you encounter an issue with your installation, so with it we can contact you with a possible fix." )" "" )"

        if ! echo "$conf_send_debug_reports_email" | grep -Eiqs '([[:alnum:]_.-]+@[[:alnum:]_.-]+?\.[[:alpha:].]{2,6})' ; then
            conf_send_debug_reports_email="$( $guitool --title='Elive Installer' --entry --width=350 --title="Email Identifier" --text="$message_email" 2>/dev/null )"
        fi
        # if ! echo "$conf_send_debug_reports_email" | grep -Eiqs '([[:alnum:]_.-]+@[[:alnum:]_.-]+?\.[[:alpha:].]{2,6})' ; then
        #     conf_send_debug_reports_email="$( $guitool --title='Elive Installer' --entry --width=350 --title="Email Identifier" --text="$message_email" 2>/dev/null )"
        # fi
        if ! echo "$conf_send_debug_reports_email" | grep -Eiqs '([[:alnum:]_.-]+@[[:alnum:]_.-]+?\.[[:alpha:].]{2,6})' ; then
            conf_send_debug_reports_email="$( $guitool --title='Elive Installer' --entry --width=350 --title="Email Identifier" --text="$message_email2" 2>/dev/null )"
        fi
        # set empty
        if ! echo "$conf_send_debug_reports_email" | grep -Eiqs '([[:alnum:]_.-]+@[[:alnum:]_.-]+?\.[[:alpha:].]{2,6})' ; then
            conf_send_debug_reports_email="no-email"
        fi
    fi


    [[ -n "$conf_send_debug_reports" ]] && el_config_save "conf_send_debug_reports"
    [[ -n "$conf_send_debug_reports_email" ]] && el_config_save "conf_send_debug_reports_email"
    # save the conf for root too, in cases that eliveinstaller will be restarted (which is then run by root)
    sudo mkdir -p "/root/.config/elive/elive-tools/el_config"
    sudo cp -a "/home/eliveuser/.config/elive/elive-tools/el_config/"* "/root/.config/elive/elive-tools/el_config/" 2>/dev/null || true

    # include variables on the installer to add in /etc/elive-version data
    export conf_send_debug_reports
    export conf_send_debug_reports_email

    # enable debug messages {{{
    if ! [[ "$EL_DEBUG" -ge 3 ]] ; then
        # note: always use debug 3, even in stable, otherwise we won't receive enough info
        #if grep -qs "stable-release: yes" /etc/elive-version ; then
            #export EL_DEBUG=2
        #else
            export EL_DEBUG=3
        #fi
    fi
    # enable colors for debug
    export LS_COLORS="rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lz=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.axa=00;36:*.oga=00;36:*.spx=00;36:*.xspf=00;36:"
    # force colors
    export TERM="xterm-256color"
    unset NOCOLOR
    # note: we need this enabled because we need to show visual messages and not reports
    export is_terminal=1
    export is_interactive=1

    # }}}

    # important to say?
    # local message_important_update
    # message_important_update="$( printf "$( eval_gettext "IMPORTANT: We have been recently reported issues installing Elive, but in all our tests the installation works correctly, if you encounter issues, can you please give us details about this problem in our forums or IRC Live chat?" )" "" )"
    #
    # $guitool --warning --text="$message_important_update"


    if [[ "$conf_send_debug_reports" = "yes" ]] ; then

        eliveversion="$( awk '$1 ~ /elive-version/ {($1="");print $0}' /etc/elive-version | sed 's/^\ //g' )"
        # do not use randomized ones, lets better identify per machine
        # id="$( dd if=/dev/urandom bs=1k count=2 2>/dev/null | sha1sum | awk '{print $1}' )"
        architecture="$( el_architecture "host" )"

        # run the installer and catch the logs
        #eliveinstaller "$@" 2>"$logs" 1>&2
        sudo -E eliveinstaller "$@" 2>"$logs" 1>&2
        exit_status="$?"


        if [[ -s "$logs" ]] && [[ "$( wc -l "$logs" | awk '{print $1}' )" -gt 20 ]] && el_verify_internet && [[ "$exit_status" != 69 ]] && ! ((is_thanatests)) ; then

            if [[ -e "/var/lib/dpkg/info/netcat-openbsd.list" ]] ; then
                # create an unique identifier
                id="$( sudo -H bash -c "source /usr/lib/elive-tools/functions ; el_get_machine_id" )"


                { echo -e "ELIVE_DATA_TYPE: 2::${id}::transfer::text::eliveinstaller_debug::0::::${conf_send_debug_reports_email}::${exit_status}::${architecture}::${eliveversion}::" ; { cat "$logs" | gzip -9 -f ; } ; } > "${logs}2"
                mv "${logs}2" "$logs"

                if nc -N www.elivecd.org 60001 -w 20 < "$logs" ; then
                    is_reports_sent=1
                else
                    sleep 2
                    if nc -N www.elivecd.org 60001 -w 30 < "$logs" ; then
                        is_reports_sent=1
                    # else
                    #     sleep 4
                    #     if nc -N www.elivecd.org 60001 -w 30 < "$logs" ; then
                    #         is_reports_sent=1
                    #     else
                    #         sleep 6
                    #         if nc -N www.elivecd.org 60001 -w 40 < "$logs" ; then
                    #             is_reports_sent=1
                    #         fi
                    #     fi
                    fi
                fi

                if [[ "$exit_status" != 0 ]] && ((is_reports_sent)) ; then

                    local message_report_id
                    # translators: the identifier is a hash (unique value like 298742935629, telling us the identifier it can be easier to find the report
                    message_report_id="$( printf "$( eval_gettext "Anonymous debugging and error information from your installation has been sent to Elive. Your feedback, especially if you encountered errors, is welcome on our forums. If you need help with your installation, referencing your identifier: \n%s will greatly improve our assistance." )" "$id" )"

                    $guitool --title='Elive Installer' --info --text="$message_report_id" 2>/dev/null || true

                    # show logs to the user too
                    zcat "$logs" 1>&2
                fi
            fi
        fi

    else
        # normal or any other "not want / not set" mode: normal install
        sudo -E eliveinstaller "$@"
        # avoid any message as "exit with error" in E from the installer (like canceled install by the user)
        true

    fi

    # reboot if was correctly installed
    if [[ -e /tmp/.eliveinstaller-just-installed ]] ; then
        if $guitool --question --text="$( eval_gettext "Would you like to reboot your computer now?" )" ; then
            (
                sync
                sleep 8 # wait enough time to send reports
                sudo reboot
            )
        fi
        rm -f /tmp/.eliveinstaller-just-installed
    fi
}

#
#  MAIN
#
main "$@"

rm -f "$lockfile"

# vim: set foldmethod=marker :
