#!/system/bin/bash
conf="/data/local/tmp/XtremeBS/XtremeBS.conf"
declare -a active_events
declare -a cpus
declare -a cpu_freqs
declare -a hp_cpus
declare -a lp_cpus
declare -a lp_govs
declare RFKILL_CMD="" # Global variable for the correct rfkill command
cpu_base_path="/sys/devices/system/cpu"

# Helpers and one time things

getconf() {
  # change made here to set default
  # if not set
  opt=$(grep "^$1=" "$conf" | cut -d= -f2)
  [ "$opt" != "" ] && echo "$opt" || echo "$2"
}

is_device() {
  # is device charging|screen|low_power
  if [ "$1" != "low_power" ]; then
    dumpsys deviceidle get $1
  else
    if [ $(settings get global low_power) = 1 ]; then
      echo true
    else
      echo false
    fi
  fi
}

notif() {
  # dont notify if notify=false
  if [ "$(getconf notify true)" = "true" ]; then
    su -lp 2000 -c "cmd notification post -S bigtext -t 'XtremeBS' 'STATUS' \"$1\"" >/dev/null
  fi
}

log_msg() {
  case $1 in
    1)
      log_lvl="[INFO]" ;;
    2)
      log_lvl="[VERBOSE]" ;;
    3)
      log_lvl="[DEBUG]" ;;
  esac
  if [ "$log_level" -ge "$1" ]; then
    echo "$(date +"%m-%d-%Y %H:%M:%S") $log_lvl $2" >> "$log_file"
  fi
}

migrate() {
  log_msg 2 "It looks like version=2 was found in the config without a valid event block"
  log_msg 1 "Migrating to v2 config"
  # start with base conf values
  # delay, version, log_file, log_level
  echo "version=2" > "$conf-v2"
  ctl_file=$(getconf ctl_file "")
  if [ ! -z "$ctl_file" ]; then
    echo "ctl_file=$ctl_file" "$conf-v2"
  fi
  delay="$(getconf delay 3)"
  echo "delay=$delay" >> "$conf-v2"
  log_file="$(getconf log_file "$(dirname "$conf")/XtremeBS.log")"
  echo "log_file=$log_file" >> "$conf-v2"
  log_level="$(getconf log_level 1)"
  echo "log_level=$log_level" >> "$conf-v2"
  # newline for clarity
  echo >> "$conf-v2"

  # start with figuring out the trigger,
  # then write values over.
  event_blocks=("charging" "screen_off")
  # events:
  # charging, screen_off, boot,
  # manual, low_power
  trigger="$(getconf trigger auto)"
  case "$trigger" in
    auto)
      event_blocks+=("manual" "boot")
      # start event block
      echo "low_power={" >> "$conf-v2"
      # keep_on_charge can be used if
      # you want the settings to persist
      # when the device is plugged in
      echo "keep_on_charge=$(getconf keep_on_charge true)" >> "$conf-v2"
      ;;
    boot)
      event_blocks+=("low_power" "manual")
      echo "boot={" >> "$conf-v2"
      # quit is a new option that can only
      # be used in a boot block. it exits the daemon
      # after making changes to keep CPU cycles to a minimum
      echo "quit=false" >> "$conf-v2"
      ;;
    manual)
      event_blocks+=("boot" "low_power")
      echo "on_start={" >> "$conf-v2"
      ;;
  esac

  # copy values over
  echo "handle_cores=$(getconf handle_cores false)" >> "$conf-v2"
  echo "disable_cores=$(getconf disable_cores false)" >> "$conf-v2"
  echo "handle_apps=$(getconf handle_apps false)" >> "$conf-v2"
  echo "allowlist=$(getconf allowlist /sdcard/XtremeBS/apps.allow)" >> "$conf-v2"
  echo "denylist=$(getconf denylist /sdcard/XtremeBS/apps.deny)" >> "$conf-v2"
  echo "handle_gms=$(getconf handle_gms false)" >> "$conf-v2"
  echo "handle_proc=$(getconf handle_proc false)" >> "$conf-v2"
  echo "proc_file=$(getconf proc_file /sdcard/XtremeBS/proc.list)" >> "$conf-v2"
  echo "low_ram=$(getconf low_ram false)" >> "$conf-v2"
  echo "doze=$(getconf doze false)" >> "$conf-v2"
  echo "kill_wifi=$(getconf kill_wifi false)" >> "$conf-v2"
  echo "}" >> "$conf-v2"
  echo >> "$conf-v2"

  # write remaining event blocks
  for event in ${event_blocks[@]}; do
    echo -e "$event={\n}\n" >> "$conf-v2"
  done

  # remove the version string and make backup
  sed -i '/^version=2/d' "$conf" # remove v2
  mv "$conf" "$conf-v1"
  # make new conf take effect
  mv "$conf-v2" "$conf"
  log_msg 1 "Migration complete!"
}

auto_map_cores() {
  log_msg 2 "Auto-mapping CPU cores"
  # high power cores
  for cpu in $(ls "$cpu_base_path/" | grep cpu[00-99]); do
    cpus+=( "$cpu" )
    cpu_freqs+=( "$(cat $cpu_base_path/$cpu/cpufreq/cpuinfo_max_freq)" )
  done
  for high_freq in $(echo "${cpu_freqs[@]}" | tr ' ' '\n' | uniq -u); do
    for index in "${!cpu_freqs[@]}"; do
      if [ "${cpu_freqs[$index]}" = "$high_freq" ]; then
        hp_cpus+=( "${cpus[$index]}" )
      fi
    done
  done
  for i in ${!hp_cpus[@]}; do
    tmp_var+="${hp_cpus[$i]} "
  done
  log_msg 3 "High power cores: $tmp_var"
  unset tmp_var
  # Low Power Cores
  for core in $(ls "$cpu_base_path/" | grep cpu[00-99]); do
    match="false"
    for hp_core in ${hp_cpus[@]}; do
      [ "$core" = "$hp_core" ] && match="true"
    done
    if [ "$match" = "false" ] && grep -q " powersave " "$cpu_base_path/$core/cpufreq/scaling_available_governors"; then
      lp_govs+=( "$(cat $cpu_base_path/$core/cpufreq/scaling_governor)" )
      lp_default_govs[$core]="$(cat $cpu_base_path/$cpu/cpufreq/scaling_governor )"
      lp_cpus+=( "$core" )
    fi
  done
    for i in ${!lp_cpus[@]}; do
    tmp_var+="${lp_cpus[$i]} "
  done
  log_msg 3 "Low power cores: $tmp_var"
  unset tmp_var
}

find_rfkill_command() {
  log_msg 2 "Searching for a valid rfkill command..."
  if command -v rfkill >/dev/null 2>&1; then
    RFKILL_CMD="rfkill"
  elif command -v toybox >/dev/null 2>&1 && toybox --help | grep -q rfkill; then
    RFKILL_CMD="toybox rfkill"
  else
    local busybox_path="$(find /data/adb/ -type f -name busybox)"
    if [ -f "$busybox_path" ] && "$busybox_path" --help | grep -q rfkill; then
      RFKILL_CMD="$busybox_path rfkill"
    fi
  fi

  if [ -n "$RFKILL_CMD" ]; then
    log_msg 2 "Found rfkill command: $RFKILL_CMD"
  else
    log_msg 2 "No rfkill command found. Will rely on svc for WiFi control."
  fi
}

update_status() {
  status_file="/data/local/tmp/XtremeBS/XtremeBS.status"
  echo -n > "$status_file"
  # CPU Map
  for i in ${!cpus[@]}; do
    core="${cpus[$i]}"
    core_list+=( "$core" )
    #is it in powersave
    core="${core_list[$i]}"
    if [ "$(cat $cpu_base_path/$core/cpufreq/scaling_governor)" = "powersave" ]; then
      tmp_var="powersave"
    fi
    # is it disabled
    if [ "$(cat $cpu_base_path/$core/online)" = "0" ]; then
      tmp_var="offline"
    fi
    core_status+=( "${tmp_var:-online}" )
    unset tmp_var
  done

  # wifi
  if [ -n "$RFKILL_CMD" ]; then
    wifi=$($RFKILL_CMD list wifi | grep "Soft" | cut -d' ' -f3)
  fi
  if [ "$wifi" = "yes" ]; then
    wifi="disabled"
  else
    wifi="enabled"
  fi

  # Doze
  unset doze
  light="$(dumpsys deviceidle get light)"
  deep="$(dumpsys deviceidle get deep)"
  if [ "$light" = "IDLE" ]; then
    doze="light"
  elif [ "$deep" = "IDLE" ]; then
    doze="deep"
  else
    doze="inactive"
  fi

  for i in ${!core_list[@]}; do
    echo "${core_list[$i]}: ${core_status[$i]}" >> "$status_file"
  done
  unset core_list core_status
  echo "Low RAM: $(getprop ro.config.low_ram)" >> "$status_file"
  echo "WiFi: $wifi" >> "$status_file"
  echo "Doze: $doze" >> "$status_file"
  unset doze wifi
}

# V1 read_config
read_config() {
  # Read config
  # delay in seconds
  delay=$(getconf delay 3)

  # trigger
  # auto|boot # <integer>
  trigger=$(getconf trigger "")
  [ -z "$trigger" ] && exit

  # Keep state on charge
  # true|false
  keep_on_charge=$(getconf keep_on_charge true)

  # handle_apps
  # false|kill|nice|suspend
  handle_apps=$(getconf handle_apps false)

  # allowlist (user apps)
  # a path /data/local/tmp/XtremeBS/apps.allow
  allowlist=$(getconf "allowlist" "/data/local/tmp/XtremeBS/apps.allow")

  # sanity check. Not allow user to suspend
  # everything without an allowlist. Will make
  # all apps unusable. Set handle_apps=false
  # and notify user
  [ ! -s "$allowlist" ] && [ "$handle_apps" = "suspend" ] && handle_apps="false" && notif "Alert!\nYou MUST have an allowlist!\nWill not suspend apps without one!"
  # log error here

  # denylist (system apps)
  # a path /data/local/tmp/XtremeBS/apps.deny
  denylist=$(getconf "denylist" "/data/local/tmp/XtremeBS/apps.deny")

  # handle_cores
  # auto|false|"cpu4 cpu5"
  handle_cores=$(getconf "handle_cores" "false")

  # disable_cores
  # false|auto|"cpu6 cpu7"
  disable_cores=$(getconf "disable_cores" "false")

  # handle_gms
  # false|kill|nice
  handle_gms=$(getconf "handle_gms" false)

  # handle_proc
  # true|false
  handle_proc=$(getconf "handle_proc" false)

  # proc_file
  # a path /data/local/tmp/XtremeBS/proc.list
  proc_file=$(getconf "proc_file" "/data/local/tmp/XtremeBS/proc.list")
  [ ! -s "$proc_file" ] && handle_proc="false"

  # set low_ram
  # true|false
  low_ram=$(getconf "low_ram" false)

  # set doze
  # false|light|deep
  doze=$(getconf doze false)

  # kill_wifi
  # true|false
  kill_wifi=$(getconf kill_wifi false)

  # May need this later
#  percent="$(dumpsys battery | grep level | cut -d' ' -f4)"

  notif "Config Loaded"
}


# Action stuff

enable_pwr_save() {
  if [ "$version" != "2" ]; then
    lock="1"
    echo -n "Enabling XtremeBS"
    notif "Enabling XtremeBS..."
    log_msg 1 "Enabling XtremeBS"
  fi
  # Handle Apps
  if [ "$handle_apps" != "false" ]; then
    for app in $(pm list packages -3 | cut -d: -f2- && [ -s "$denylist" ] && cat "$denylist"); do
      if grep -q -E "$app" "$allowlist"; then
        continue
      fi
      if [ "$handle_apps" = "nice" ]; then
        for i in $(pgrep "$app"); do
          log_msg 3 "Renicing $i"
          renice -n 19 "$i" &>/dev/null &
        done
      elif [ "$handle_apps" = "kill" ]; then
        log_msg 3 "Stopping $app"
        am force-stop "$app" &>/dev/null &
      else
        log_msg 3 "Suspending $app"
        am force-stop "$app" &>/dev/null &
        pm suspend "$app" &>/dev/null &
      fi
    done
  fi

  # Handle GMS , this will be leaving soon.
  # Not many need it, and proc_file can handle it
  if [ "$handle_gms" = "nice" ]; then
    log_msg 3 "Renicing GMS"
    renice -n 19 "$(pgrep com.google.android.gms)"
  elif [ "$handle_gms" = "kill" ]; then
    log_msg 3 "Disabling GMS"
    pm disable com.google.android.gms
    am force-stop com.google.android.gms
  else
    : # Do nothing
  fi
  # Handle processes
  if [ "$handle_proc" = "true" ]; then
    while [ "$lock" = "1" ]; do
      while read proc nice; do
        pid="$(pgrep $proc)"
        [ ! "$nice" ] && nice="10"
        if [ "$(cat /proc/$pid/stat | cut -d' ' -f19)" != "$nice" ]; then
          log_msg 3 "Renicing $proc to $nice"
          renice -n "$nice" "$pid"
        fi
      done < "$proc_file"
      sleep "$delay"
    done &
  fi
  # Low RAM
  if [ "$low_ram" = "true" ]; then
    log_msg 3 "Setting the low_ram flag"
    resetprop -n ro.config.low_ram true
  fi

  # Handle WiFi
  if [ "$kill_wifi" = "true" ]; then
    log_msg 3 "Disabling WiFi"
    if [ -n "$RFKILL_CMD" ]; then
      log_msg 3 "Attempting to block with: $RFKILL_CMD"
      "$RFKILL_CMD" block wifi
      
      # Check if rfkill actually worked, if not, use svc as a final fallback
      if [ "$("$RFKILL_CMD" list wifi | grep Soft | cut -d: -f2 | cut -d' ' -f2)" != "yes" ]; then
         log_msg 3 "rfkill failed to block. Falling back to svc."
         svc wifi disable
      fi
    else
      log_msg 3 "No rfkill command available. Using svc."
      svc wifi disable
    fi
  fi

  # Handle Doze
  if [ "$doze" = "light" ]; then
    log_msg 3 "Enabling $doze Doze mode"
    dumpsys deviceidle force-idle light &>/dev/null
  fi
  if [ "$doze" = "deep" ]; then
    log_msg 3 "Enabling $doze Doze mode"
    dumpsys deviceidle force-idle deep &>/dev/null
  fi

  # Handle Cores

  if [ "$handle_cores" != "false" ] || [ "$disable_cores" != "false" ]; then
    if [ -d "/data/adb/modules" ]; then
      # magisk mount read-write
      magic_remount_rw &>/dev/null
    fi
    if [ "$disable_cores" = "auto" ]; then
      for cpu in ${hp_cpus[@]}; do
        log_msg 3 "Disabling $cpu"
        echo "0" > "$cpu_base_path/$cpu/online"
      done
    else
      # manual
      for core in $disable_cores; do
        if [ -d "$cpu_base_path/$core" ]; then
          log_msg 3 "Disabling $core"
          echo "0" > "$cpu_base_path/$core/online"
        fi
      done
    fi
    if [ "$handle_cores" = "auto" ]; then
      for cpu in ${lp_cpus[@]}; do
        log_msg 3 "Setting powersave on $cpu"
        echo "powersave" > "$cpu_base_path/$cpu/cpufreq/scaling_governor"
      done
    else
      # manual
      for core in $handle_cores; do
        [ -d "$cpu_base_path/$core/" ] && \
        grep -q " powersave " "$cpu_base_path/$core/cpufreq/scaling_available_governors" && \
        log_msg 3 "Setting powersave on $core" && \
        echo "powersave" > "$cpu_base_path/$cpu/cpufreq/scaling_governor"
      done
    fi
    if [ -d "/data/adb/modules" ]; then
      # magisk mount read-only
      magic_remount_ro &>/dev/null
    fi
  fi

  if [ "$version" != "2" ]; then
    echo " - [done]"
    notif "status: Enabled"
    log_msg 1 "Enabled XtremeBS"
  fi

  update_status
}

disable_pwr_save() {
  if [ "$version" != "2" ]; then
    echo -n "Disabling XtremeBS"
    notif "Disabling XtremeBS..."
    log_msg 1 "Disabling XtremeBS"
  fi
  # Handle Cores

  if [ "$handle_cores" != "false" ] || [ "$disable_cores" != "false" ]; then
    if [ -d "/data/adb/modules" ]; then
      # magisk mount read-write
      magic_remount_rw &>/dev/null
    fi
    if [ "$disable_cores" = "auto" ]; then
      for cpu in ${hp_cpus[@]}; do
        log_msg 3 "Enabling $cpu"
        echo "1" > "$cpu_base_path/$cpu/online"
      done
    else
      # the user manually set it
      for cpu in $disable_cores; do
        if [ -d "$cpu_base_path/$cpu/" ]; then
          log_msg 3 "Enabling $cpu"
          echo "1" > "$cpu_base_path/$cpu/online"
        fi
      done
    fi
    if [ "$handle_cores" = "auto" ]; then
      for index in ${!lp_cpus[@]}; do
        # TBH, i have no fucking clue
        # what i did here but its
        # magical and it works
        # so, i will just leave it.
        log_msg 3 "Resetting ${lp_cpus[$index]}"
        echo "${lp_govs[$index]}" > "$cpu_base_path/${lp_cpus[$index]}/cpufreq/scaling_governor"
      done
    else
      # the user manually set it
      for cpu in $handle_cores; do
        if [ -d "$cpu_base_path/$cpu/" ]; then
          log_msg 3 "Resetting $cpu"
          echo "${lp_default_govs[$cpu]}" > "$cpu_base_path/$cpu/cpufreq/scaling_governor"
        fi
      done
    fi
    if [ -d "/data/adb/modules" ]; then
      # magisk mount read-only
      magic_remount_ro &>/dev/null
    fi
  fi

  # Handle Doze
  if [ "$doze" != "false" ]; then
    log_msg 3 "Disabling Doze mode"
    dumpsys deviceidle unforce &>/dev/null
  fi

  # Handle WiFi
  if [ "$kill_wifi" = "true" ]; then
    log_msg 3 "Enabling WiFi"
    if [ -n "$RFKILL_CMD" ]; then
      log_msg 3 "Attempting to unblock with: $RFKILL_CMD"
      "$RFKILL_CMD" unblock wifi
      
      # Check if rfkill actually worked, if not, use svc as a final fallback
      if [ "$("$RFKILL_CMD" list wifi | grep Soft | cut -d: -f2 | cut -d' ' -f2)" != "no" ]; then
         log_msg 3 "rfkill failed to unblock. Falling back to svc."
         svc wifi enable
      fi
    else
      log_msg 3 "No rfkill command available. Using svc."
      svc wifi enable
    fi
  fi

  # Handle Apps
  if [ "$handle_apps" != "false" ]; then
    for app in $(pm list packages -3 | cut -d: -f2- && [ -s "$denylist" ] && cat "$denylist"); do
      if grep -q -E "$app" "$allowlist"; then
        continue
      fi
      if [ "$handle_apps" = "nice" ]; then
        for i in $(pgrep "$app"); do
          log_msg 3 "Resetting the nice level for $app"
          renice -n 0 "$i" &>/dev/null &
        done
      else
        log_msg 3 "Unsuspending $app"
        pm unsuspend "$app" &>/dev/null &
      fi
    done
  fi

  # Handle GMS
  if [ "$handle_gms" = "nice" ]; then
    log_msg 3 "Resetting the nice level for GMS"
    renice -n 0 "$(pgrep com.google.android.gms)"
  elif [ "$handle_gms" = "kill" ]; then
    log_msg 3 "Enabling GMS"
    pm enable com.google.android.gms
  else
    : # Do nothing
  fi
  # Handle Processes
  if [ "$handle_proc" = "true" ]; then
    while read proc nice; do
      log_msg 3 "Resetting the nice level for $proc"
      renice -n 0 "$(pgrep $proc)"
    done < "$proc_file"
  fi
  # Low RAM
  if [ "$low_ram" = "true" ]; then
    log_msg 3 "Setting low_ram to false"
    resetprop -n ro.config.low_ram false
  fi

  if [ "$version" != "2" ]; then
    lock="0"
    echo " - [done]"
    notif "status: Disabled"
    log_msg 1 "Disabled XtremeBS"
  fi

  update_status
}

# Event stuff for V2

is_event_locked() {
  event="$1"
  for i in ${!active_events[@]}; do
    if [ "${active_events[$i]}" = "$event" ]; then
      return 1
    fi
  done
  return 0
}

handle_event() {
  event="$1"
  flag="$2"

  if [ "$flag" = 1 ]; then # we are trying to enable
    # check to see if its unlocked
    is_event_locked "$event"
    if [ $? != 0 ]; then
      # we tried to enable an already active event
      log_msg 2 "$event was triggered but it is currently enabled"
      # return early
      return 1
    else
      # lock the event
      active_events+=( "$event" )
    fi
  fi

  # set everything to false
  quit=false
  handle_cores=false
  disable_cores=false
  handle_apps=false
  allowlist=null
  denylist=null
  handle_proc=false
  proc_file=null
  handle_gms=false
  low_ram=false
  doze=false
  kill_wifi=false

  log_msg 3 "Parsing the config for $event event"

  # parse config of event
  line=''
  while read line; do
    [ "$line" = "$event={" ] && continue
    [ "$line" = "}" ] && break
    key=$(echo "$line" | cut -d= -f1)
    val=$(echo "$line" | cut -d= -f2-)
    case $key in
      keep_on_charge)
        if [ "$val" = "true" ] && \
        [ "$flag" = "0" ] && \
        [ "$event" != "charging" ] && \
        [ "$charging" = "true" ]; then
          log_msg 1 "$event has keep_on_charge set. We are keeping the settings until unplugged"
          return 0
        fi ;;
      quit)
        if [ "$val" = "true" ] && \
        [ "$event" = "boot" ]; then
          quit=true
        fi ;;
      handle_cores)
        if [ "$val" != "false" ]; then
          handle_cores="$val"
        fi ;;
      disable_cores)
        if [ "$val" != "false" ]; then
          disable_cores="$val"
        fi ;;
      handle_apps)
        if [ "$val" != "false" ]; then
          handle_apps="$val"
        fi ;;
      allowlist)
        if [ -f "$val" ]; then
          allowlist="$val"
        fi ;;
      denylist)
        if [ -f "$val" ]; then
          denylist="$val"
        fi ;;
      handle_proc)
        if [ "$val" != "false" ]; then
          handle_proc="$val"
        fi ;;
      proc_file)
        if [ -f "$val" ]; then
          proc_file="$val"
        fi ;;
      handle_gms)
        if [ "$val" != "false" ]; then
          handle_gms="$val"
        fi ;;
      low_ram)
        if [ "$val" = "true" ]; then
          low_ram="true"
        fi ;;
      doze)
        if [ "$val" != "false" ]; then
          doze="$val"
        fi ;;
      kill_wifi)
        if [ "$val" = "true" ]; then
          kill_wifi="true"
        fi;;
    esac
  done < <(grep -A99 "$event={" "$conf")

  # perform sanity checks to prevent the user from killing themself
  if [ "$handle_apps" != "false" ] && [ "$allowlist" = "null" ] && [ "$denylist" = "null" ]; then
    handle_apps=false
  fi
  if [ "$handle_proc" != "false" ] && [ "$proc_file" = "null" ]; then
    handle_proc="false"
  fi

  # perform action using the old way
  # instead of a massive refactor which
  # is probably coming in a later update
  if [ "$flag" = 0 ]; then
    log_msg 1 "Undoing actions for $event"
    disable_pwr_save
    # remove from active_events
    for i in ${!active_events[@]}; do
      if [ "${active_events[$i]}" = "$event" ]; then
        unset "active_events[$i]"
      fi
    done
    log_msg 1 "Actions for $event undone"
  else
    log_msg 1 "Performing actions for $event event"
    enable_pwr_save
    log_msg 1 "Actions for $event completed"
    if [ "$event" = "boot" ] && \
    [ "$quit" = "true" ]; then
      log_msg 1 "Boot event has the quit option set. Killing the daemon."
      exit 0
    fi
  fi

  # build the active events notification
  for i in ${!active_events[@]}; do
    active_notif+="${active_events[$i]} "
  done

  notif "Active Events: $active_notif"
  unset active_notif
}

init_v2() {

handle_event boot 1
charging="$(is_device charging)"
if [ "$charging" = "true" ]; then
  handle_event charging 1
fi
was_charging="$charging"
low_power="$(is_device low_power)"
if [ "$low_power" = "true" ]; then
  handle_event low_power 1
fi
was_low_power="$low_power"
screen_on="$(is_device screen)"
# here we invert because we only want to
# do something if the screen is off
if [ "$screen_on" = "false" ]; then
  handle_event screen_off 1
fi
was_screen_on="$screen_on"

while true; do

  # Check for command
  cmd="$(cat $ctl_file)"
  cmd_event=$(echo "$cmd" | cut -d' ' -f2)
  cmd=$(echo "$cmd" | cut -d' ' -f1)
  echo > "$ctl_file"
  case $cmd in
    reload)
      # reload is for top level config opts
      for i in ${!active_events[@]}; do
        handle_event "${active_events[$i]}" 0
      done
      log_msg 2 "Reloading the config"
      exec "$0"
      ;;
    start)
      if [ ! "$cmd_event" ]; then
        log_msg 1 "The start command was received. Starting manual event"
        handle_event manual 1
      else
        log_msg 1 "The start command was received. Attempting to start $cmd_event"
        handle_event "$cmd_event" 1
      fi
      ;;
    stop)
      if [ ! "$cmd_event" ]; then
        log_msg 1 "The stop command was received. Stopping manual event"
        handle_event manual 0
      else
        log_msg 1 "The stop command was received. Attempting to start $cmd_event"
        for i in ${!active_events[@]}; do
          if [ "${active_events[$i]}" = "$cmd_event" ]; then
            handle_event "${active_events[$i]}" 0
          fi
        done
      fi
      ;;
    pause)
      until [ "$resume" = "resume" ]; do
        sleep "$delay"
        resume="$(cat $ctl_file)"
      done ;;
    safe)
      log_msg 1 "Entered Safe Mode"
      echo "safemode=1" >> "$conf"
      for i in ${!active_events[@]}; do
        handle_event "${active_events[$i]}" 0
      done
      for pkg in $(pm list packages | cut -d: -f2-); do
        pm unsuspend "$pkg"
      done
      notif "Safe Mode is Active"
      until [ "$ready" = "resume" ]; do
        ready="$(cat $ctl_file)"
      done
      log_msg 1 "Resume command received. Safe Mode Exited."
      sed -i '/safemode=1/d' "$conf"
      exec "$0"
      ;;
    *)
      :
      ;;
  esac

  # check charging state
  charging=$(is_device charging)
  if [ "$was_charging" != "" ]; then
    if [ "$charging" != "$was_charging" ]; then
      log_msg 2 "Charging event was triggered"
      if [ "$charging" = "true" ]; then
        handle_event charging 1
      else
        handle_event charging 0
      fi
    fi
  fi
  was_charging="$charging"

  # check low_power state
  low_power=$(is_device low_power)
  if [ "$was_low_power" != "" ]; then
    if [ "$low_power" != "$was_low_power" ]; then
      log_msg 2 "Low Power event was triggered"
      if [ "$low_power" = "true" ]; then
        handle_event low_power 1
      else
        handle_event low_power 0
      fi
    fi
  fi
  was_low_power="$low_power"

  # check screen change
  screen_on=$(is_device screen)
  if [ "$was_screen_on" != "" ]; then
    if [ "$screen_on" != "$was_screen_on" ]; then
      log_msg 2 "Screen change was detected"
      # here we invert because we only want to
      # do something if the screen is off
      if [ "$screen_on" = "false" ]; then
        handle_event screen_off 1
      else
        handle_event screen_off 0
      fi
    fi
  fi
  was_screen_on="$screen_on"

  sleep "$delay"
done
}

init_v1() {
  read_config
  while true; do
    # Check for command
      cmd="$(cat $ctl_file)"
      echo > "$ctl_file"
      case $cmd in
        reload)
          log_msg 1 "Reload command received"
          if [ "$lock" = "0" ]; then
            read_config
          else
            disable_pwr_save
            read_config
            enable_pwr_save
          fi
          log_msg 1 "Config reloaded"
          ;;
        stop)
          log_msg 1 "Stop command received"
          if [ "$lock" = "1" ]; then
            if [ "$trigger" != "manual" ]; then
              if [ "$tr_changed" = "true" ]; then
                trigger="$old_trigger"
                tr_changed="false"
              else
                old_trigger="$trigger"
                trigger="manual"
                tr_changed="true"
              fi
            fi
            disable_pwr_save
          fi
          log_msg 1 "Stopped XtremeBS"
          ;;
        start)
          log_msg 1 "Start command received"
          if [ "$lock" = "0" ]; then
            if [ "$trigger" != "manual" ]; then
              if [ "$tr_changed" = "true" ]; then
                trigger="$old_trigger"
                tr_changed="false"
              else
                old_trigger="$trigger"
                trigger="manual"
                tr_changed="true"
              fi
            fi
            enable_pwr_save
          fi
          log_msg 1 "Started XtremeBS"
          ;;
        pause)
          log_msg 1 "Pause command received"
          until [ "$resume" = "resume" ]; do
            sleep "$delay"
            resume="$(cat $ctl_file)"
          done
          log_msg 1 "Resume command received"
          ;;
        safe)
          echo "safemode=1" >> "$conf"
          log_msg 1 "Entering Safe Mode"
          disable_pwr_save
          # enhance safemode here
          # unsuspend all apps here
          # in the event every app
          # got suspended
          #
          # i think this will work.
          # not tested due to lazyness
          for pkg in $(pm list packages | cut -d: -f2-); do
            pm unsuspend "$pkg"
          done
          notif "Safe Mode is Active"
          until [ "$ready" = "resume" ]; do
            ready="$(cat $ctl_file)"
          done
          sed -i '/safemode=1/d' "$conf"
          log_msg 1 "Resume command received. Safe Mode Exited. Restarting Daemon."
          exec "$0"
          ;;
        *)
          :
          ;;
      esac

    # Check for trigger
    if [ "$trigger" = "boot" ]; then
      if [ "$lock" != "1" ]; then
        enable_pwr_save
      fi
    elif [ "$trigger" = "auto" ]; then
      if [ "$(settings get global low_power)" = "1" ] && [ "$lock" = "0" ]; then
        enable_pwr_save
      fi
      if [ "$(settings get global low_power)" = "0" ] && [ "$lock" = "1" ]; then
        if [ "$keep_on_charge" = "false" ] || [ "$(getstate charging)" = "false" ]; then
            disable_pwr_save
        fi
      fi
    else
      : # Do nothing, its Manual here
    fi

    # Wait
    sleep "$delay"
  done

}

# START

# setup config (v1 is default... for now...)

[ ! -d /data/local/tmp/XtremeBS/ ] && mkdir /data/local/tmp/XtremeBS/

if [ ! -s "$conf" ]; then
  cat << EOF > "$conf"
# trigger
# auto|boot|manual
trigger=auto

# this will make version 2 the default (Mwahahahahaha)
version=2

# log file
log_file=/sdcard/XtremeBS.log

# log level
log_level=1

# delay
# time in seconds
delay=3

# keep_on_charge
# true|false
# keep powersave on while charging
keep_on_charge=true

# handle_cores
# auto|false|"cpu4 cpu5"
handle_cores=false

# disable_cores
# false|auto|"cpu6 cpu7"
disable_cores=false

# handle_apps
# false|kill|nice|suspend
handle_apps=false

# allowlist (user apps)
# a path /data/local/tmp/XtremeBS/apps.allow
allowlist=/data/local/tmp/XtremeBS/apps.allow

# denylist (system apps)
# a path /data/local/tmp/XtremeBS/apps.deny
denylist=/data/local/tmp/XtremeBS/apps.deny

# handle_gms
# false|kill|nice
handle_gms=false

# handle_proc
# true|false
handle_proc=false

# process list
# a path /data/local/tmp/XtremeBS/proc.list
proc_file=/data/local/tmp/XtremeBS/proc.list

# low_ram
# true|false
low_ram=false

# doze
# false|light|deep
doze=false

#kill_wifi
# true|false
kill_wifi=false

EOF

fi

# check for migration
version="$(getconf version 1)" # if version is not set, it is 1
# check for a user wanting to switch to v2
if [ "$(grep ".*={" "$conf" | head -n 1)" == "" ] && [ "$version" = "2" ]; then
  migrate
fi

# setup logging
log_file=$(getconf log_file "/sdcard/XtremeBS.log")
log_level=$(getconf log_level 3) # set debug by default

# this fixes the infinite growth issue
[ -f "$log_file" ] && mv "$log_file" "$log_file.old"

# set ctl_file
ctl_file=$(getconf ctl_file "/data/local/tmp/xbs")

# persistent safe mode
safe=$(getconf safemode 0)
if [ "$safe" = "1" ]; then
  log_msg 1 "Safemode was found in the config file, Entering safemode."
  notif "Safe Mode is Active"
  until [ "$resume" = "resume" ] || [ $(getconf safemode 0) = "0" ]; do
    resume=$(cat "$ctl_file")
  done
  sed -i '/safemode=1/d' "$conf"
  sed -i '/safemode=0/d' "$conf"
  log_msg 1 "Safemode was exited. Restarting the daemon."
  exec "$0"
fi

delay=$(getconf delay 3)

# auto map cores in case we need them
auto_map_cores

# Find the rfkill command once and for all
find_rfkill_command

# check version and init
if [ "$version" = 2 ]; then
  log_msg 1 "Starting XtremeBS"
  init_v2
else
  log_msg 1 "Starting XtremeBS in compatibility mode"
  log_msg 1 "You should consider migrating to v2 of the config"
  log_msg 1 "You can migrate by putting version=2 in your config"

  lock="0" # fix all the checks v1
  tr_changed="false" # v1 trigger changed

  init_v1
fi
