#!/bin/bash
STARTVERSION="2.1.0"

/home/andrew/splash.sh &
SPLASHPID=$(echo $!)

echo "Turning off Autosuspend on USB devices"
echo -1 > /sys/module/usbcore/parameters/autosuspend

echo "Turning Off CPU Auto Power Control"
echo 0 > /sys/devices/system/cpu/cpuquiet/tegra_cpuquiet/enable

echo "Turning On all CPU's"
echo 1 > /sys/devices/system/cpu/cpu1/online
echo 1 > /sys/devices/system/cpu/cpu2/online
echo 1 > /sys/devices/system/cpu/cpu3/online
echo 1 > /sys/devices/system/cpu/cpu4/online
echo 1 > /sys/devices/system/cpu/cpu5/online

echo "Enabling Performance Optimization"
echo performance > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
echo performance > /sys/devices/system/cpu/cpu1/cpufreq/scaling_governor
echo performance > /sys/devices/system/cpu/cpu2/cpufreq/scaling_governor

sudo jetson_clocks

echo "CPU's Active"
cat /sys/devices/system/cpu/online

echo "CPU 0 Frequency"
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq

echo "CPU 1 Frequency"
cat /sys/devices/system/cpu/cpu1/cpufreq/scaling_cur_freq

echo "CPU 2 Frequency"
cat /sys/devices/system/cpu/cpu2/cpufreq/scaling_cur_freq

echo "CPU 3 Frequency"
cat /sys/devices/system/cpu/cpu3/cpufreq/scaling_cur_freq

echo "CPU 4 Frequency"
cat /sys/devices/system/cpu/cpu4/cpufreq/scaling_cur_freq

echo "CPU 5 Frequency"
cat /sys/devices/system/cpu/cpu5/cpufreq/scaling_cur_freq

#sudo mount /dev/sda1 /media/andrew/datapartition/

#I2S setup
sudo devmem2 0x02434000 h 0x454
sudo devmem2 0x02434008 h 0x404
sudo devmem2 0x02434010 h 0x444
sudo devmem2 0x02434018 h 0x444

# sudo devmem2  0x0c302020 h 0x400
# sudo devmem2  0x0c302018 h 0x450

cd /home/andrew/Desktop
sudo rmmod imx219
sudo systemctl stop nvargus-daemon
sudo systemctl stop serial-getty@ttyS0.service
sudo systemctl stop serial-getty@ttyS2.service

sudo echo pll_p_out0 >  /sys/kernel/debug/bpmp/debug/clk/uartc/parent
sudo echo 1843200  >  /sys/kernel/debug/bpmp/debug/clk/uartc/rate

sudo insmod imx219.ko
#sudo rmmod snd-soc-tlv320adc310x
sudo insmod snd-soc-tlv320adc310x.ko
sudo insmod /home/andrew/Desktop/pl2303.ko
sleep .2

amixer -c  tegrasndt186ref sset "I2S2 Mux" ADMAIF1
amixer -c  tegrasndt186ref sset "ADMAIF1 Mux" I2S2
#pactl set-default-sink alsa_output.platform-3510000.hda.hdmi-stereo-extra1

 sudo gpasswd --add ${USER} dialout
# sudo gpasswd --add ${USER} tty

echo 306 > /sys/class/gpio/export  #Buzzer
echo out  > /sys/class/gpio/gpio306/direction

echo 276 > /sys/class/gpio/export  #Rec LED
echo out  > /sys/class/gpio/gpio276/direction
echo 1 > /sys/class/gpio/gpio276/value

echo 290 > /sys/class/gpio/export  #485 RDE (1)
echo out  > /sys/class/gpio/gpio290/direction

echo 291 > /sys/class/gpio/export  #485 RDE (2)
echo out  > /sys/class/gpio/gpio291/direction

echo 376 > /sys/class/gpio/export  #Record
echo in  > /sys/class/gpio/gpio376/direction

echo 377 > /sys/class/gpio/export  #stop/up
echo in  > /sys/class/gpio/gpio377/direction

echo 378 > /sys/class/gpio/export  #photo
echo in  > /sys/class/gpio/gpio378/direction

echo 379 > /sys/class/gpio/export  #pause/down
echo in  > /sys/class/gpio/gpio379/direction

echo 483 > /sys/class/gpio/export  #Move/Left
echo in  > /sys/class/gpio/gpio483/direction

echo 273 > /sys/class/gpio/export  #PIP/Esc
echo in  > /sys/class/gpio/gpio273/direction

echo 274 > /sys/class/gpio/export  #Menu/Sel
echo in  > /sys/class/gpio/gpio274/direction

echo 275 > /sys/class/gpio/export  #Swap/Right
echo in  > /sys/class/gpio/gpio275/direction

echo 264 > /sys/class/gpio/export  #Front C HPD
echo in  > /sys/class/gpio/gpio264/direction
sudo devmem2 0x0c301080 h 0x58 #gpio 264 pull-up enable

echo 269 > /sys/class/gpio/export  #SATA mux select
echo out  > /sys/class/gpio/gpio269/direction
echo 1  > /sys/class/gpio/gpio269/value # set to PCIe

echo 392 > /sys/class/gpio/export  #Video 4 reset
echo out  > /sys/class/gpio/gpio392/direction
echo 1  > /sys/class/gpio/gpio392/value

echo 393 > /sys/class/gpio/export  #Video 1 reset
echo out  > /sys/class/gpio/gpio393/direction
echo 1  > /sys/class/gpio/gpio393/value

echo 394 > /sys/class/gpio/export  #Video 3 reset
echo out  > /sys/class/gpio/gpio394/direction
echo 1  > /sys/class/gpio/gpio394/value

echo 395 > /sys/class/gpio/export  #Video 2 reset
echo out  > /sys/class/gpio/gpio395/direction
echo 1  > /sys/class/gpio/gpio395/value

echo 410 > /sys/class/gpio/export #BT enable
echo out > /sys/class/gpio/gpio410/direction
echo 1 > /sys/class/gpio/gpio410/value

echo 408 > /sys/class/gpio/export #wifi enable
echo out > /sys/class/gpio/gpio408/direction
echo 1 > /sys/class/gpio/gpio408/value


valid_script() {  # $1 = path; returns 0 if the file is usable
    [ -f "$1" ] || return 1
    [ "$(stat -c%s "$1" 2>/dev/null || echo 0)" -ge 2048 ] || return 1   #Blank
    bash -n "$1" >/dev/null 2>&1 || return 1                             #Check line endings
    return 0
}

#while ![xhost >& /dev/null] ; do
#:
#echo "Display does not exists"
#done
#sudo xinit

sudo ln -sf /home/andrew/Desktop/1.16.3/build/gst/libgstreamer-1.0.so.0.1603.0 /usr/lib/aarch64-linux-gnu/libgstreamer-1.0.so.0
sudo ln -sf /home/andrew/Desktop/1.16.3/build/gst/libgstreamer-1.0.so.0.1603.0 /usr/lib/aarch64-linux-gnu/libgstreamer-1.0.so

cd /home/andrew

if valid_script "kiosk_session2.sh"; then
    rm kiosk_session.sh
    mv kiosk_session2.sh kiosk_session.sh
    sudo chmod 777 kiosk_session.sh
fi

if valid_script "monitor_manager2.sh"; then
    rm monitor_manager.sh
    mv monitor_manager2.sh monitor_manager.sh
    sudo chmod 777 monitor_manager.sh
fi

if ! valid_script "startauto.sh"; then
    rm startauto.sh
    cp start.sh startauto.sh
    sudo chmod 777 startauto.sh
    sync -d startauto.sh
fi



cd /home/andrew/Desktop/ShareContext

if test -f overlay2; then #if an update has been added
    if [ "$(stat -c%s overlay2 2>/dev/null || echo 0)" -ge 1048576 ]; then #Make sure that the binary is at least 1MB
        if test -f overlayBackup; then #if there is already a backup
            rm overlayBackup
        fi
        mv overlay overlayBackup
        mv overlay2 overlay
        sudo chmod 777 overlay
        rm save.dat
        rm save2.dat
        echo Success > UPDATE_SUCCESS
    else # invalid update binary, just delete it
        echo "$(date '+%Y-%m-%d %H:%M:%S') overlay2 invalid (truncated?); update aborted" > UPDATE_FAILED
        rm -f overlay2
    fi
fi

if [ ! -f overlay ]; then #if an update broke the old one
    cp overlayBackup overlay
    sudo chmod 777 overlay
fi

if [ "$(stat -c%s overlay 2>/dev/null || echo 0)" -le 1048576 ]; then #Make sure that the binary is at least 1MB
    cp overlayBackup overlay
    sudo chmod 777 overlay
fi
sleep 5


DRIVES=$(ls /media/andrew/  ) # remove all unmounted dead folders

for t in $DRIVES ; do  # for entries in DRIVE
	MOUTPOINT=$(df -h /media/andrew/$t | tail -n 1 | awk -F " " '{print $1}' | grep /dev/root)
	if test ${#MOUTPOINT} != '0' ; then
	    sudo rm -r /media/andrew/$t
	fi
done

DRIVES=$(ls /media/andrew/  ) # remove all mounted dead folders

for t in $DRIVES ; do  # for entries in DRIVE
	MOUTPOINT=$(lsblk | grep $(df -h /media/andrew/$t | tail -n 1 | awk -F " " '{print $1}' | awk -F / '{print $3}'))
	if test ${#MOUTPOINT} == '0' ; then
	    #echo need to remove $t
	    sudo umount /media/andrew/$t
	    sudo rm -r /media/andrew/$t
	fi
done

DRIVES=$(lsblk | grep sd | cut -c 7-11 | grep sd) # find all atatched drives and copy into DRIVE array

for t in $DRIVES ; do  # for entries in DRIVE
     TEMP=$(readlink -f /sys/class/block/$t/device | grep usb) #if DRIVE is not on USB,
     if [ ${#TEMP} = "0" ] ; then   # then mount it as hard drive
	echo  mounting "$t" as internal drive
	mkdir /media/andrew/datapartition/
	sudo umount /media/andrew/$(lsblk | grep $t | awk -F / '{print $4}')
	sudo mount -t exfat /dev/$t /media/andrew/datapartition/
	sudo mount -o remount,rw /media/andrew/datapartition/
        mkdir /media/andrew/datapartition/videoout
     else
	echo not mounting "$t" as internal drive length ${#TEMP}
     fi
done

find /media/andrew/datapartition/videoout/ -maxdepth 1 -name ".fuse_hidden*" -delete

sudo kill -9 $SPLASHPID

KIOSK="/home/andrew/kiosk_session.sh"
KIOSK_DEFAULT="/home/andrew/kiosk_session.default.sh"

USE_KIOSK=1

if ! valid_script "$KIOSK"; then
    echo "WARNING: $KIOSK is missing, blank, or invalid."
    if valid_script "$KIOSK_DEFAULT"; then
        echo "Restoring backup kiosk from $KIOSK_DEFAULT"
        cp "$KIOSK_DEFAULT" "$KIOSK"
        chmod 777 "$KIOSK"
    fi
    if ! valid_script "$KIOSK"; then
        echo "No valid kiosk available, using raw overlay fallback."
        USE_KIOSK=0
    fi
fi


# Pick the real keyboard: a kbd device whose capability bitmap has both
# KEY_ESC (bit 1) and KEY_LEFTSHIFT (bit 42). Skips gpio-keys and mouse nodes.
KBD=$(awk 'BEGIN{RS="";FS="\n"}
/Handlers=.*kbd/ {
    dev=""; key="";
    for(i=1;i<=NF;i++){
        if($i ~ /Handlers=/ && match($i,/event[0-9]+/)) dev=substr($i,RSTART,RLENGTH);
        if($i ~ /^B: KEY=/){ key=$i; sub(/^B: KEY=/,"",key); }
    }
    gsub(/ +$/,"",key);
    n=split(key,g," "); last=g[n];
    while(length(last)<16) last="0" last;
    if(dev!="" && index("2367abef",substr(last,16,1)) && index("4567cdef",substr(last,6,1))){
        print "/dev/input/" dev; exit }
}' /proc/bus/input/devices)

# Wait up to $1 seconds for Shift+Esc on $KBD. Returns 0 if seen, 1 otherwise.
wait_shiftesc() {
    local budget=$1 remain deadline ev shift=0
    [ -n "$KBD" ] && [ -r "$KBD" ] || { sleep "$budget"; return 1; }
    deadline=$(( $(date +%s) + budget ))
    while remain=$(( deadline - $(date +%s) )); [ "$remain" -gt 0 ]; do
        ev=$(timeout "${remain}s" dd bs=384 count=1 status=none < "$KBD" 2>/dev/null \
             | od -An -w24 -v -tu1)
        [ -z "$ev" ] && continue                       # timed out, no event
        local -a b
        while read -r -a b; do
            [ "${#b[@]}" -lt 21 ] && continue
            [ "$(( b[16] + b[17]*256 ))" -eq 1 ] || continue      # EV_KEY only
            case "$(( b[18] + b[19]*256 ))" in                    # keycode
                42|54) [ "${b[20]}" -ne 0 ] && shift=1 || shift=0 ;;   # L/R Shift
                1)     [ "${b[20]}" -eq 1 ] && [ "$shift" -eq 1 ] && return 0 ;; # Esc press
            esac
        done <<< "$ev"
    done
    return 1
}


COUNTER=20
FASTFAILS=0
while test $COUNTER -ge 0 ; do

    echo "Preparing X Session..."
    #check that there is at least one HDMI connected, otherwise overlay will fail to launch
    while [ "$(awk -F= '/^HDMI[0-9]*=/{s+=$2} END{print s+0}' /sys/class/extcon/*/state 2>/dev/null)" -le 0 ] ; do
        echo "No monitor found. Waiting for HDMI...  (Shift+Esc to drop to console)"
        if wait_shiftesc 5; then
            echo "Shift+Esc pressed - exiting startup, console is available."
            exit 0
        fi
    done

    # 1. CLEANUP STALE LOCKS (The Fix)
    # Remove the main auth file and any lock (-c, -l) files left over
    rm -f /home/andrew/.Xauthority
    rm -f /home/andrew/.Xauthority-c
    rm -f /home/andrew/.Xauthority-l

    # Remove temporary server auth files in /tmp
    rm -f /tmp/serverauth.*
    rm -f /tmp/.X0-lock

    START_TS=$(date +%s)

    if [ "$USE_KIOSK" -eq 1 ] && test -f /home/andrew/kiosk_session.sh; then #if a valid kiosk session exists

        echo "Starting Kiosk..."

        # 2. Start X
        startx  /home/andrew/kiosk_session.sh $STARTVERSION -- -nocursor
           echo "Session ended. Restarting in 1 second..."
        sleep 1
    else
        echo "Just launching overlay..."
        HOME=/home/andrew sudo STARTVERSION=0.1.0 CONFIGURATION=RELEASE startx ./overlay --screen 0 1920x1080 --screen 1 1920x1080

    fi

    END_TS=$(date +%s)
    ELAPSED=$((END_TS - START_TS))
    echo "Session ended after ${ELAPSED}s."

    # Let the operator drop to console between crash/relaunch cycles too.
    if wait_shiftesc 1; then
        echo "Shift+Esc pressed - exiting startup, console is available."
        exit 0
    fi

    # Only an instant death counts toward the backup-restore budget. A healthy
    # session (ran >=10s, i.e. a monitor was present and the binary worked)
    # refills the budget so a working unit never marches toward the destructive
    # restore. After 3 instant kiosk deaths, fall back to raw overlay so a broken
    # kiosk cannot brick the boot.
    if [ "$ELAPSED" -lt 10 ]; then
        FASTFAILS=$((FASTFAILS + 1))
        let "COUNTER=COUNTER-1"
        if [ "$USE_KIOSK" -eq 1 ] && [ "$FASTFAILS" -ge 3 ]; then
            echo "Kiosk session failing instantly, switching to raw overlay fallback."
            USE_KIOSK=0
            FASTFAILS=0
        fi
    else
        FASTFAILS=0
        COUNTER=20
    fi

    sleep 1
done


# Reaching here means ~20 instant-death launches with a monitor present =>
# the binary itself is bad. Restore the previous binary and reboot.
cd /home/andrew/Desktop/ShareContext
if test -f overlayBackup; then #if there is already a backup
    rm overlay
    cp overlayBackup overlay
    sudo chmod 777 overlay
    echo failed > UPDATE_FAILED
    rm save*
    reboot
fi
