#!/usr/bin/env bash

###############################################
## script for instantOS autostart            ##
###############################################

INSTANTVERSION="$(cat /usr/share/instantutils/version)"
if iconf version && [ "$(iconf version)" = "$INSTANTVERSION" ]; then
    echo "version check successful"
    echo "running version $INSTANTVERSION"
else
    echo "running update hooks"
    /usr/share/instantutils/userinstall.sh
    iconf -i userinstall 1
    iconf version "$INSTANTVERSION"
    instantutils default
fi

# architecture detection
if [ -z "$1" ]; then
    if uname -m | grep -q '^arm'; then
        export ISRASPI=true
    fi

    if iconf -i noautostart; then
        echo "autostart disabled"
        exit
    fi

    if [ "$(ps aux | grep bash | grep instantautostart | wc -l)" -gt 3 ]; then
        echo "already running"
        exit
    fi
else
    echo "forced run"
fi

cd || {
    notify-send 'there seems to be a problem with your home directory, autostart failed'
    exit 1
}

ins autostart

if command -v pamac &>/dev/null && idate m pamacupdate; then
    timeout 30 pamac update &
fi

# find out if it's a live session
if [ -e /usr/share/liveutils ] &>/dev/null; then
    ISLIVE="True"
    echo "live session detected"
fi

if iconf -i islaptop; then
    export ISLAPTOP="true"
    echo "laptop detected"
else
    echo "not a laptop"
fi

islive() {
    if [ -n "$ISLIVE" ]; then
        return 0
    else
        return 1
    fi
}

if [ -n "$ISRASPI" ]; then
    # enable double drawing for moving floating windows
    # greatly increases smoothness
    iconf -i highfps 1
    if ! [ -e ~/.config/instantos/israspi ]; then
        echo "marking machine as raspi"
        mkdir -p ~/.config/instantos
        touch ~/.config/instantos/israspi
        # logo does not work on raspi
        iconf -i nologo 1
    fi
fi

xrdb ~/.Xresources

startdunst() {
    mkdir -p /tmp/notifications &>/dev/null
    # wait for theming to finish before starting dunst
    # TODO: come up with something better than a constant wait time
    sleep 5
    if ! pgrep dunst; then
        while :; do
            dunst
            sleep 2
        done &
    fi
}

startdunst &

# fix resolution on virtual machine
if ! iconf -i novmfix && grep -q 'hypervisor' /proc/cpuinfo; then
    # indicator file only exists on kvm/QEMU on amd
    if [ -e /opt/instantos/kvm ]; then
        iconf -i highfps 1
        if lshw -c video | grep -i 'qxl' || xrandr | grep -i '^qxl'; then
            iconf -i qxl 1
            # iconf -i noanimations 1
            if ! iconf -i potato && ! iconf -i nopotato; then
                if echo "please set your video card to virtio or passthrough
QXL on AMD on QEMU/kvm has been known to cause a severe Xorg memory leak. 
Disabling compositing makes this somewhat bearable,
but switching really is recommended.
(or switch to virtualbox, no issues there...)
Disable compositing for this VM?" | ins menu confirm; then
                    iconf -i potato 1
                    pkill picom
                else
                    if ! ins menu confirm "ask again next time?"; then
                        iconf -i nopotato 1
                    fi
                fi
            fi
        else
            iconf -i qxl 1
        fi
    fi

    if ! [ -e /opt/instantos/guestadditions ]; then
        if lsmod | grep -q vboxguest && ! {
            [ "$(xrandr | head -1 | grep -o 'current [0-9]* *x *[0-9]*' | sed 's/[a-zA-Z ]//g')" = "800600" ]
        }; then
            echo "guestadditions detected"
        else
            if echo "virtual machine detected.
Would you like to switch to a 1080p resolution?" | ins menu confirm; then
                echo "applying virtual machine workaround"
                VDISPLAY="$(xrandr 2>/dev/null | grep ' connected' | grep -o '^[^ ]*' | head -1)"
                if [ -n "$VDISPLAY" ]; then
                    xrandr --newmode "1920x1080_60.00" 172.80 1920 2040 2248 2576 1080 1081 1084 1118 -HSync +Vsync 2>/dev/null || true
                    xrandr --addmode "$VDISPLAY" "1920x1080_60.00" 2>/dev/null || true
                    xrandr --output "$VDISPLAY" --mode "1920x1080_60.00" 2>/dev/null || true
                fi
            else
                if [ -z "$ISLIVE" ]; then
                    if ! ins menu confirm "ask again next session"; then
                        iconf -i novmfix 1
                    fi
                fi
            fi
        fi
    fi
fi

if ! islive; then
    echo "not a live session"

    cd ~/instantos || exit 1
    if ! iconf -i max; then
        instantmonitor
    fi

    if [ -e ~/instantos/monitor.sh ]; then
        echo "restoring resolution"
        bash ~/instantos/monitor.sh &
    elif [ -e ~/.config/autorandr/instantos/config ]; then
        echo "restoring autorandr resolution"
        autorandr instantos &
    fi

    if ! iconf -i noconky; then
        instantutils conky
    fi

    if id instantsupport &>/dev/null; then
        if echo 'your computer might have been restarted or crashed during an instantSUPPORT session
This caused some leftover configuration that can pose a security risk. Clean that up now?' | ins menu confirm; then
            instantsudo instantsupport -c
            notify-send 'cleaned up instantsupport leftovers'
        fi
    fi

else
    echo "live session detected"
    instantmonitor

    echo "disabling compositing for qxl graphics"
    if lshw -c video | grep -i 'qxl' || xrandr | grep -i '^qxl'; then
        iconf -i potato 1
    fi

    sudo systemctl start NetworkManager

    iconf -i wifiapplet 1
    instantwallpaper set /usr/share/instantwallpaper/defaultphoto.png
    conky -c /usr/share/instantwidgets/install.conf &
    # Refresh the package-managed installer before exposing launch actions.
    # A failed refresh is non-fatal: the ISO-bundled version remains usable.
    sudo liveautostart
    installapplet &
    ins welcome --gui --force-live &
    sleep 1

fi

#TODO: move this into `ins settings`
offerdpi() {
    HEIGHT=$(iconf max | grep -o '[0-9]*$')
    WIDTH=$(iconf max | grep -o '^[0-9]*')
    RESOLUTION="$((HEIGHT * WIDTH))"
    DPIMESSAGE="HiDpi settings can be found in settings->display->dpi"
    if ! ins menu confirm "high resolution display detected
would you like to enable HiDpi?"; then
        if ins menu confirm "ask again next time?"; then
            return
        fi
        iconf -i nohidpi 1
        ins menu message "$DPIMESSAGE"
        return
    fi

    DPI=$(ins menu input 'enter dpi (default is 96)')
    while ! [ "$DPI" -eq "$DPI" ] || [ "$DPI" -gt 500 ] || [ "$DPI" -lt "20" ]; do
        ins menu message "please enter a number between 20 and 500 (default is 96), enter q to skip hidpi"
        DPI=$(ins menu input 'enter dpi (default is 96)')
        if grep -q 'q' <<<"$DPI"; then
            ins menu message "$DPIMESSAGE"
            return
        fi
    done

    iconf dpi "$DPI"

    instantdpi
    xrdb ~/.Xresources
    ins menu message "a restart is needed to globally apply dpi"

}

if ! iconf -i nohidpi && iconf max; then
    if [ "$RESOLUTION" -gt 8294000 ]; then
        offerdpi
    fi
fi

# compositing
if iconf -i potato || iconf -i nocompositing; then
    echo "compositing disabled"
else
    ipicom &
fi

# auto open menu when connecting/disconnecting monitor
checkautoswitch() {
    {
        iconf -i islaptop && ! iconf -i noautoswitch
    } || iconf -i autoswitch || return 1
}

getdisplaycount() {

    # xrandr lags some nvidia gpus, use nvidia-xconfig instead if present
    if [ -n "$HASNVIDIA" ] || nvidia-xconfig --query-gpu-info; then
        DISPLAYCOUNT="$(nvidia-xconfig --query-gpu-info | grep -oi 'number of dis.*' | grep -o '[0-9]*')"
        export HASNVIDIA="true"
    else
        DISPLAYCOUNT="$(xrandr | grep -c '[^s]connected')"
    fi

}

if checkautoswitch; then
    DISPLAYCOUNT="$(getdisplaycount)"

    if [ "$DISPLAYCOUNT" -eq "$DISPLAYCOUNT" ]; then
        while :; do
            if ! checkautoswitch; then
                # autoswitch was disabled this boot
                sleep 30
                continue
            fi
            NEWDISPLAYCOUNT="$(getdisplaycount)"
            if ! [ "$DISPLAYCOUNT" = "$NEWDISPLAYCOUNT" ]; then
                notify-send "display changed"
                echo "displays changed"
                if [ "$NEWDISPLAYCOUNT" -gt 1 ]; then
                    instantdisper
                    echo "multi monitor setup"
                else
                    autorandr horizontal
                fi
                DISPLAYCOUNT="$NEWDISPLAYCOUNT"
                # todo: open menu
                if pgrep conky; then
                    pkill conky
                    instantutils conky
                fi
            fi
            sleep 6
            command -v udevwait && udevwait
        done &
    else
        echo "error detecting display count"
    fi
fi

# prompt to fix configuration if installed from the AUR
if ! iconf -i norootinstall && ! islive; then
    if ! command -v ins || ! command -v instantmenu; then
        notify-send "please install instantCLI and instantmenu"
    else
        if ! [ -e /opt/instantos/rootinstall ]; then
            ins menu message "instantOS is missing some configuration"
            while ! [ -e /tmp/rootskip ]; do
                if ins menu confirm "would you like to fix that?"; then
                    touch /tmp/topinstall
                    instantsudo bash -c "instantutils root"
                    touch /tmp/rootskip
                else
                    if ins menu confirm "Are you sure? this will prevent parts of instantOS from functioning correctly"; then
                        touch /tmp/rootskip
                    fi
                fi

            done
        fi
    fi
fi

if idate d dailyroutine; then
    menuclean
fi

# run command if iconf option is set
confcommand() {
    if iconf -i "$1"; then
        shift 1
        "$@"
    fi &
}

if iconf savebright; then
    export NOBRIGHTMESSAGE=true
    ins assist bright "$(iconf savebright)" 2>/dev/null || true
fi

if iconf -i alttab; then
    instantwmctl alttab 3
else
    instantwmctl alttab 1
fi

# user declared autostart
if [ -e ~/.config/instantos/autostart.sh ]; then
    bash ~/.config/instantos/autostart.sh
fi &

if ! iconf -i nodesktopautostart; then
    # start all .desktop programs from ~/.config/autostart
    for f in ~/.config/autostart/*.desktop; do
        [ -f "$f" ] || break
        if ! grep -q -E "NotShowIn=.*(;|)default" <"$f"; then
            gio launch "$f" &
        fi
    done
fi

# update notifier
if ! iconf -i noupdates && [ -z "$ISLIVE" ]; then
    sleep 2m
    if checkinternet; then
        instantupdatenotify
    else
        if command -v checkinternet; then
            while :; do
                sleep 5m
                if checkinternet; then
                    instantupdatenotify
                    break
                fi
            done
        fi
    fi
fi &

# needed for graphical root prompts
# TODO: replace with systemd?
while :; do
    lxqt-policykit-agent
    sleep 2
done &

if ! [ -e ~/.config/instantos/default/browser ]; then
    # generate symlinks that point to default applications
    instantutils default
fi

# start processes that need to be kept running
while :; do
    sleep 5
    # check if new device has been plugged in and apply settings
    # TODO: look into slowing this down with udevwait
    XINPUTSUM="$(xinput | md5sum)"
    if ! [ "$OLDXSUM" = "$XINPUTSUM" ]; then
        OLDXSUM="$XINPUTSUM"
        instantmouse gen
        applymouse
    fi
    sleep 2
    if iconf -i wifiapplet && ! pgrep nm-applet; then
        echo "starting wifi applet"
        nm-applet &
    fi
    sleep 2
    if iconf -i bluetoothapplet && ! pgrep blueman-applet; then
        echo "starting bluetooth applet"
        blueman-applet &
    fi

    # TODO: make instantWM alttab binding toml configurable

    sleep 1m
done
