#!/usr/bin/env bash

DEBUG=0 #should be 0 in release!!!!!!!!!!
LOG_FILE="/var/log/8mknet.log"

if [[ -z $MKNET_AUTOFAN_CONF ]]; then #reread env variables as after upgrade this can be empty
  source /etc/environment
  export $(cat /etc/environment | grep -vE '^$|^#' | cut -d= -f1) #export all variables from file
fi

source colors

MAINTENANCE_SEM_NAME="/tmp/8mknet_autofan_maintenance"
CLI_OUTPUT="/run/hive/8mknet_autofan"
OUTPUT_TTL=30
CLI_LATEST_OK_STAT="/run/hive/8mknet_latest_ok"
LATEST_TTL=120
MKNET_PORT=

check_config() {
  if [ ! -f "$MKNET_AUTOFAN_CONF" ]; then
    echo2 "${RED}No config $MKNET_AUTOFAN_CONF${NOCOLOR}"
  fi
}

check_sem() {
if [[ -f $MAINTENANCE_SEM_NAME ]]; then
  a=0
  let a=`date +%s`-`stat --format='%Y' $MAINTENANCE_SEM_NAME`
  if [[ a -le 60 ]]; then
    #echo2 "8MK_NET is in maintenance mode. Command ignored."
    return 1 #8MK_NET is in maintenance mode
  else
    return 0
  fi
fi
}

get_file_time_diff(){
  local a=999
  [[ -f "$1" ]] && let a=`date +%s`-`stat --format='%Y' "$1"`
  echo $a
}

start_listner(){
  stty -F "$MKNET_PORT" raw ispeed 9600 ospeed 9600 -ignpar cs8 -cstopb -echo
  sleep 0.2

  screen -dm -c /hive/opt/8mknet/screenrc.8mknet_autofan cat "$MKNET_PORT"
  for i in {1..25}; do
    sleep 0.2 #it needs some time? it happens that you'll have "No screen session found" without sleep
    local session_count=0
    session_count=`screen -ls 8mknet_autofan | grep -c "8mknet_autofan"`
    [[ $session_count -gt 0 ]] && break #echo -e "Found screen miner in $i iterations" &&
    [[ $i -ge 25 ]] && echo -e "${RED}screen 8MK_NET not found in 25 iterations, check logs and maybe flash drive speed${NOCOLOR}"
  done
}

stop_listner(){
  local screens=(`screen -ls 8mknet_autofan | grep -Po "\K[0-9]+(?=\.8mknet_autofan)" | sort --unique`)
  for pid in "${screens[@]}"; do
    timeout 1 screen -S $pid.8mknet_autofan -X quit
  done

  #removing listner output
  rm -f $CLI_OUTPUT
#  rm -f ${CLI_OUTPUT}_50
}

send_request(){
  check_sem
  [[ $? -ne 0 ]] && return 1 #coolbox is in maintenance mode

  #check 8MK_NET listner
  local session_count=0
  session_count=`screen -ls 8mknet_autofan | grep -c "8mknet_autofan"`
  if [[ $session_count -eq 0 ]]; then #starting 8MK_NET listner
    start_listner
  fi

  if [[ `get_file_time_diff $CLI_OUTPUT` -gt 30 ]]; then
    stop_listner
    start_listner
  fi

  echo -n $1 > $MKNET_PORT
  sleep 2

  if [[ -f ${CLI_OUTPUT} ]]; then
    local rtn=""
    rtn=`tail -1 ${CLI_OUTPUT}`
    echo "$rtn"
  fi
}

get_stats(){
#  cache disabled becouse now there are several commands

  #read config
  if [[ -f "$MKNET_AUTOFAN_CONF" ]]; then #in case serial verification error no conf will be received
    source "$MKNET_AUTOFAN_CONF"
  fi

  [[ $AUTO_ENABLED -eq 0 ]] && FAN_MODE=1 || FAN_MODE=2

  temp_array=
  mtemp_array=
  #check $GPU_STATS_JSON and do nothing while not exist
  if [ -f "$GPU_STATS_JSON" ]; then
    temp_array=`cat "$GPU_STATS_JSON" | tail -1 | jq -c ".temp"`
    mtemp_array=`cat "$GPU_STATS_JSON" | tail -1 | jq -c ".mtemp"`

    local cpu_indexes_array='[]'
    cpu_indexes_array=`cat "$GPU_DETECT_JSON" | jq -c '[ . | to_entries[] | select(.value.brand == "cpu") | .key ]'` #'

    #remove Internal Gpus
    if [[ $cpu_indexes_array != '[]' && ! -z $cpu_indexes_array ]]; then
      temp_array=$(jq -c "del(.$cpu_indexes_array)" <<< "$temp_array") #"
      if [[ mtemp_array != 'null' ]]; then
        mtemp_array=$(jq -c "del(.$cpu_indexes_array)" <<< "$mtemp_array") #"
      fi
    fi
  fi
  temp_array=${temp_array//\"}
  mtemp_array=${mtemp_array//\"}

  [[ -z $TARGET_TEMP ]] && TARGET_TEMP=60
  [[ -z $TARGET_MEM_TEMP ]] && TARGET_MEM_TEMP=90
  [[ -z $MANUAL_FAN ]] && MANUAL_FAN=50
  [[ -z $FAN_MODE ]] && FAN_MODE=1
  [[ -z $MIN_FAN ]] && MIN_FAN=30
  [[ -z $MAX_FAN ]] && MAX_FAN=100

  request_str='{"gpu_temp":'$temp_array',"gpu_mtemp":'$mtemp_array',"target_temp":'$TARGET_TEMP',"target_mtemp":'$TARGET_MEM_TEMP',"manual_fan_speed":'$MANUAL_FAN',"fan_mode":'$FAN_MODE',"min_fan":'$MIN_FAN',"max_fan":'$MAX_FAN'}'

  debug_out $request_str

  send_request "$request_str"
}

debug_out() {
  if [[ $DEBUG -eq 1 ]]; then
    echo `date`": $@" >> $LOG_FILE
  fi
}

get_json(){
  local answer=`get_stats`
  echo "$answer" | jq '.thermosensors' >> /dev/null 2>&1
  if [[ $? -eq 0 ]] && [[ $answer =~ "thermosensors" ]]; then
    debug_out $answer
    echo "$answer" | jq -c '.' > $CLI_LATEST_OK_STAT
    echo "$answer" | jq -c '.'
  else
    if [[ `get_file_time_diff $CLI_LATEST_OK_STAT` -le $LATEST_TTL ]]; then
      debug_out "CACHED VALUE!" $answer
      cat $CLI_LATEST_OK_STAT
    else
      debug_out "Stats read error"
      echo "{}"
    fi
  fi
}

check_hw(){
  if [[ `lsusb -v -d 10c4:ea60 | grep iSerial | awk '{print $3}'` == 'Autofan8MK_NET' ]]; then
    MKNET_PORT=/dev/ttyUSB0
    return 0
  fi
  return 1
}

get_model(){
  lsusb -v -d 10c4:ea60 2>/dev/null | grep iProduct | awk '{print $3}'
}

if check_hw; then
  if [[ $1 == "--get_json" ]]; then
    get_json
  elif [[ $1 == "--model" ]]; then
    get_model
  elif [[ $1 == "--check_hw" ]]; then
    exit 0
  else
    echo "Error: wrong command."
    exit 1
  fi
else
  if [[ $1 == "--get_json" ]]; then
    echo "{}"
  elif [[ $1 == "--check_hw" ]]; then
    exit 1
  else
    echo "No MK8_NET Autofan found"
  fi
  exit 1
fi
