#!/usr/bin/bash

# Trip point 0: when temperature goes down, this is the point where we boost things again
TRIP_POINT_0=88000

# Trip point 1: activate cooling devices (reduces cpu speed)
TRIP_POINT_1=91000

# Trip point 2: too late!
TRIP_POINT_2=94000

# Get CPU speed range
MIN_FREQ_0=$(cat /sys/devices/system/cpu/cpufreq/policy0/cpuinfo_min_freq)
MAX_FREQ_0=$(cat /sys/devices/system/cpu/cpufreq/policy0/cpuinfo_max_freq)

if [ -e /sys/devices/system/cpu/cpufreq/policy4/ ]; then
    HAS_FREQ_4=1
    MIN_FREQ_4=$(cat /sys/devices/system/cpu/cpufreq/policy4/cpuinfo_min_freq)
    MAX_FREQ_4=$(cat /sys/devices/system/cpu/cpufreq/policy4/cpuinfo_max_freq)
fi

# ---------------------------------------------------------------------------------------------------------------------

function create_new_csv_file {
    # create a new unique file
    index=$(ls /data/temperature_*.csv 2>/dev/null | wc -l)
    index=$(printf "%03d" $((index+1)))
    csvfile="/data/temperature_${index}.csv"

    # CSV header/fields
    if [ -n "${HAS_FREQ_4}" ]; then
        echo "Time (s),Temperature (deg),Clock Speed 1 (MHz),Clock Speed 2 (MHz)" > ${csvfile}
    else
        echo "Time (s),Temperature (deg),Clock Speed (MHz)" > ${csvfile}
    fi

    # print file path
    echo ${csvfile}
}

function append_csv_data {
    time=$((csvstep * 5))
    temp=$((cur_temp / 1000))
    freq=$((cur_freq / 1000))

    if [ -n "${HAS_FREQ_4}" ]; then
        freq4=$((cur_freq4 / 1000))
        echo "${time},${temp},${freq},${freq4}" >> ${csvfile}
    else
        echo "${time},${temp},${freq}" >> ${csvfile}
    fi

    # increase for next time
    csvstep=$((csvstep + 1))
}

# ---------------------------------------------------------------------------------------------------------------------

function too_hot {
    if [ ${cur_temp} -ge ${TRIP_POINT_1} ]; then
        echo "Activating cooling devices"
        echo 1 > /sys/class/thermal/cooling_device0/cur_state
        if [ -e /sys/class/thermal/cooling_device1/cur_state ]; then
            echo 1 > /sys/class/thermal/cooling_device1/cur_state
        fi
        if systemctl -q is-active mod-noise-removal; then
            systemctl stop mod-noise-removal
        fi
    fi
    if [ ${cur_temp} -ge ${TRIP_POINT_2} ]; then
        echo "Killing JACK (I am sorry...)"
        killall jackd
    fi
}

function too_cold {
    echo "Deactivate cooling device"
    echo 0 > /sys/class/thermal/cooling_device0/cur_state
    if [ -e /sys/class/thermal/cooling_device1/cur_state ]; then
        echo 0 > /sys/class/thermal/cooling_device1/cur_state
    fi
    if ! systemctl -q is-active mod-noise-removal; then
        systemctl start mod-noise-removal
    fi
}

function init_loop {
    cur_freq=$(cat /sys/devices/system/cpu/cpufreq/policy0/cpuinfo_cur_freq)
    if [ -n "${HAS_FREQ_4}" ]; then
    cur_freq4=$(cat /sys/devices/system/cpu/cpufreq/policy4/cpuinfo_cur_freq)
    fi
    cur_temp=$(cat /sys/class/thermal/thermal_zone0/temp)
    prev_temp=${cur_temp}
    # append_csv_data

    # Check if temperature exceeds first tripping point
    if [ ${cur_temp} -ge ${TRIP_POINT_1} ]; then
        too_hot
    fi

    if [ -n "${HAS_FREQ_4}" ]; then
        echo "cpu-freq-manager started. temp:${cur_temp} freq:${cur_freq},${cur_freq4}"
    else
        echo "cpu-freq-manager started. temp:${cur_temp} freq:${cur_freq}"
    fi
}

function run_loop {
    cur_freq=$(cat /sys/devices/system/cpu/cpufreq/policy0/cpuinfo_cur_freq)
    if [ -n "${HAS_FREQ_4}" ]; then
    cur_freq4=$(cat /sys/devices/system/cpu/cpufreq/policy4/cpuinfo_cur_freq)
    fi
    cur_temp=$(cat /sys/class/thermal/thermal_zone0/temp)
    # append_csv_data

    if [ ${prev_temp} != ${cur_temp} ]; then
        # Check if temperature exceeds first tripping point
        if [ ${cur_temp} -ge ${TRIP_POINT_1} ]; then
            if [ ${cur_temp} -lt ${prev_temp} ]; then
                if [ -n "${HAS_FREQ_4}" ]; then
                    echo "cpu-freq-manager run_loop HOT cooling down, skipped. temp:${cur_temp} freq:${cur_freq},${cur_freq4}"
                else
                    echo "cpu-freq-manager run_loop HOT cooling down, skipped. temp:${cur_temp} freq:${cur_freq}"
                fi
            else
                too_hot
            fi

        # Check if temperature is below any tripping point
        elif [ ${cur_temp} -le ${TRIP_POINT_0} ]; then
            if [ ${cur_temp} -gt ${prev_temp} ]; then
                if [ -n "${HAS_FREQ_4}" ]; then
                    echo "cpu-freq-manager run_loop COLD heating up, skipped. temp:${cur_temp} freq:${cur_freq},${cur_freq4}"
                else
                    echo "cpu-freq-manager run_loop COLD heating up, skipped. temp:${cur_temp} freq:${cur_freq}"
                fi
            else
                too_cold
            fi

        fi
    fi

    prev_temp=$(cat /sys/class/thermal/thermal_zone0/temp)
}

# ---------------------------------------------------------------------------------------------------------------------

# init global vars
prev_temp=0
cur_freq=0
cur_temp=0

# csvfile=$(create_new_csv_file)
# csvstep=0

# ---------------------------------------------------------------------------------------------------------------------

# Activate userspace
echo userspace > /sys/devices/system/cpu/cpufreq/policy0/scaling_governor

if [ -n "${HAS_FREQ_4}" ]; then
    echo userspace > /sys/devices/system/cpu/cpufreq/policy4/scaling_governor
fi

# set frequency to max possible
echo ${MAX_FREQ_0} > /sys/devices/system/cpu/cpufreq/policy0/scaling_setspeed

if [ -n "${HAS_FREQ_4}" ]; then
    echo ${MAX_FREQ_4} > /sys/devices/system/cpu/cpufreq/policy4/scaling_setspeed
fi

init_loop

while true; do
    if sleep 5; then
        run_loop
    else
        break
    fi
done

# ---------------------------------------------------------------------------------------------------------------------
