#!/usr/bin/env bash

# $1 Auto updater
# $2 Disable TUI
# $3 Init

AUTO_UPDATER_ENABLED=${1:-false}
DISABLE_TUI=${2:-false}
INIT=${3:-false}

SUDO=${CH_SUDO:-sudo}

set -e

configfile="./scripts/updater-preferences"

# Verify that we aren't root
if [ $(id -u) -eq 0 ]; then
    echo -e "\033[1;33m \n \nThis script must'nt be run as root!\n\033[0m"
    exit 1
fi

LOCKFILE=/tmp/chupdater.lock
if [ -e ${LOCKFILE} ] && ps -p `cat ${LOCKFILE}` >/dev/null; then
    echo -e "\033[1;33m \n \nUpdater: Updater already running!\n\033[0m"
    exit 1
fi

# make sure the lockfile is removed when we exit and then claim it
trap "rm -f ${LOCKFILE}; exit" INT TERM EXIT
echo $$ > ${LOCKFILE}

. ./scripts/config.shlib

# If the config file doesn't exist, create it
if [ ! -e ${configfile} ]; then
    touch ${configfile}
fi

#Check if TUI is available
tui=true
dialog=true
if [ ! -t 0 ]; then
    tui=false
fi
if [ "$DISABLE_TUI" == "true" ]; then
    tui=false
fi
if [ ! -x "$(command -v dialog)" ] || [ "$tui" == false ]; then
    dialog=false
    if [ "$tui" == true ]; then
        echo -e "\033[1;31mTerminal UI NOT supported! Install \"dialog\"! \033[0m"
    fi
fi

# Run migrations if not a developer
exists=true
cfg_haskey $configfile update_channel || exists=false
if [ "$exists" == true ]; then
    update_channel="$(cfg_read $configfile update_channel)"
fi
if [ "$update_channel" != "developer" ]; then
    ./scripts/migrations $tui $INIT true || exit 1
fi

# Ask the user if they want to enable the auto updater
exists=true
cfg_haskey $configfile autoupdater || exists=false
if [ "$dialog" == true ] && [ "$exists" == false ]; then
    value=true
    response=255
    while [ "$response" != 0 ] && [ "$response" != 1 ]; do
        dialog --keep-tite --title "Updater"  --yesno "Do you want to enable the cathook auto updater?" 10 25 || { response=$?; continue; }
        response=$?
    done
    if [ "$response" == 1 ]; then
        value=false
    fi
    cfg_write $configfile autoupdater $value
fi

# Send notice about auto updater, terminate script if its not enabled
exists=true
cfg_haskey $configfile autoupdater || exists=false
if [ "$AUTO_UPDATER_ENABLED" == "true" ]; then
    if [ $exists == false ] || [ "$(cfg_read $configfile autoupdater)" == false ]; then
        exit 0;
    fi
    AUTOUPDATER=true
    tui=false
    echo -e "\033[1;34m \n \nAuto Updater: Updating cathook in the background\n\033[0m"
fi

function performupdate() {
    # If init, then update_channel isn't set yet. Assume stable.
    if [ "$INIT" == true ]; then
        update_channel="stable"
    else
        #get update channel from config
        exists=true
        cfg_haskey $configfile update_channel || exists=false
        if [ "$exists" ==  true ]; then
            update_channel="$(cfg_read $configfile update_channel)"
        else
            update_channel="invalid"
        fi
    fi
    
    if [ "$update_channel" == "stable" ]; then
        git fetch --force --depth 1 origin refs/tags/stable:refs/tags/stable && git reset --hard stable || { echo -e "\033[1;33m\nFailed to pull from github! Trying alternative pull (legacy)\n\033[0m"; git fetch --depth 1 && git reset --hard @{upstream} || { echo -e "\033[1;31m\nFailed to pull from github! A reinstall is recommended. https://github.com/nullworks/cathook\n\033[0m"; exit 1; } }
    elif [ "$update_channel" == "master" ]; then
        git fetch --force --depth 1 origin && git reset --hard origin/master || { echo -e "\033[1;33m\nFailed to pull from github! Trying alternative pull (legacy)\n\033[0m"; git fetch --depth 1 && git reset --hard @{upstream} || { echo -e "\033[1;31m\nFailed to pull from github! A reinstall is recommended. https://cathook.club\n\033[0m"; exit 1; } }
    elif [ "$update_channel" == "developer" ]; then
        echo -e "\033[1;33m\nWarning! Running in developer mode! Expect issues!\n\033[0m" && git pull origin || { echo -e "\033[1;31m\n\nFailed to pull from github!\n\033[0m"; exit 1; }
    else
        if [ "$dialog" == true ]; then
            value=true
            dialog --keep-tite --title "Updater"  --yesno "Unknown update channel or version. Restore to stable update channel and reset version?" 10 25 || value=false
            if [ "$value" == true ]; then
                # force reinit
                ./scripts/migrations $tui true false || exit 1
            fi
        fi
        exit 1
    fi
    
    # Run migrations 
    if [ "$update_channel" != "developer" ]; then
        ./scripts/migrations $tui $INIT false || exit 1
    fi
    
    # Check if all required packages are installed
    ./scripts/dependencycheck
    
    # Submodules
    if [ "$update_channel" == "developer" ]; then
        git submodule update --init --recursive
    else
        git submodule sync > /dev/null
        git submodule update --depth 1 --init --recursive
    fi

    # Make sure that the auto updater only uses 1 core for compiling
    proccount=$(grep -c '^processor' /proc/cpuinfo)
    if [ "$AUTOUPDATER" == true ]; then
        proccount=1
    fi
    
    #Create build folder in case it doesn't exist
    mkdir -p ./build
    # Update cathook
    pushd build && cmake .. && cmake --build . --target cathook -- -j$proccount || { echo -e "\033[1;31m \n \nFailed to compile cathook\n\033[0m"; exit 1; }
    # Update data
    cwd="$(pwd)"
    cmake --build . --target data || { echo -e "\033[1;31m\nFailed to update /opt/cathook/data directory! Trying with root rights!\n\033[0m"; $SUDO bash -c "cd \"$cwd\"; cmake --build . --target data" || { echo -e "\033[1;31m\nFailed to update /opt/cathook/data directory\n\033[0m"; exit 1; } }
    popd
    echo -e "\n\033[1;34mCathook updated successfully\n\033[0m"
    rm -f ${LOCKFILE}
}

if [ $AUTOUPDATER ]; then
    performupdate &
else
    performupdate
fi
