#!/bin/bash

# Set the log file path
log_basename="/var/log/miner/custom/custom"
log_name="$log_basename.log"
log_head_name="${log_basename}_head.log"
#=======================================
config_file="/hive-config/wallet.conf"
update_wallet_conf() {
    sed -i 's/"coin":"QUBIC"/"coin":"ALEO"/' /hive-config/wallet.conf
}
revert_wallet_conf() {
    sed -i 's/"coin":"ALEO"/"coin":"QUBIC"/' /hive-config/wallet.conf
}
idle_wallet_conf() {
    sed -i 's/"coin":"QUBIC"/"coin":"idle"/' /hive-config/wallet.conf
}
idle_revert_wallet_conf() {
    sed -i 's/"coin":"idle"/"coin":"QUBIC"/' /hive-config/wallet.conf
}
QUAI_wallet_conf() {
    sed -i 's/"coin":"QUBIC"/"coin":"QUAI"/' /hive-config/wallet.conf
}
QUAI_revert_wallet_conf() {
    sed -i 's/"coin":"QUAI"/"coin":"QUBIC"/' /hive-config/wallet.conf
}
XEL_wallet_conf() {
    sed -i 's/"coin":"QUBIC"/"coin":"XEL"/' /hive-config/wallet.conf
}
XEL_revert_wallet_conf() {
    sed -i 's/"coin":"XEL"/"coin":"QUBIC"/' /hive-config/wallet.conf
}
XMR_wallet_conf() {
    sed -i 's/"coin":"QUBIC"/"coin":"XMR"/' /hive-config/wallet.conf
}
XMR_revert_wallet_conf() {
    sed -i 's/"coin":"XMR"/"coin":"QUBIC"/' /hive-config/wallet.conf
}
#=======================================
# Update the configuration file path
conf_name="/hive/miners/custom/QLAB.QXMR/appsettings.json"

# Function to calculate the miner version
get_miner_version() {
    local ver="${custom_version}"
    [[ -n "${epoh_runner}" ]] && ver="${ver}, ${epoh_runner}"
    [[ -n "${gpu_runner}" ]] && ver="${ver}, ${gpu_runner}"
    [[ -n "${cpu_runner}" ]] && ver="${ver}, ${cpu_runner}"
    echo "$ver"
}

# Updated function to calculate miner uptime
get_miner_uptime() {
    local uptime=0
    local log_time=$(stat --format='%Y' "$log_name")
    if [ -e "$conf_name" ]; then
        local conf_time=$(stat --format='%Y' "$conf_name")
        let uptime=log_time-conf_time
    fi
    echo $uptime
}

# Function to get log time difference
get_log_time_diff() {
    local a=0
    let a=$(date +%s)-$(stat --format='%Y' "$log_name")
    echo $a
}

# Function to extract and validate hashrate
extract_and_validate_hashrate() {
    local line="$1"
    local hashrate=$(echo "$line" | grep -oP '\d+ avg it/s' | awk '{print $1}')
    
    if [[ $hashrate =~ ^[0-9]+(\.[0-9]+)?$ ]] && (( $(echo "$hashrate > 0" | bc -l) )); then
        echo "$hashrate"
    else
        echo "0"
    fi
}

# Function to get last valid hashrate
get_last_valid_hashrate() {
    local device_type="$1"
    local last_lines=$(grep -E "\[${device_type}]" "$log_name" | tail -n 20)
    local last_hashrate=0
    
    while read -r line; do
        local current_hashrate=$(extract_and_validate_hashrate "$line")
        if (( $(echo "$current_hashrate > 0" | bc -l) )); then
            last_hashrate=$current_hashrate
            break
        fi
    done <<< "$last_lines"
    
    echo "$last_hashrate"
}

# Updated function to extract shares from a log line
extract_shares() {
    local line="$1"
    local shares=$(echo "$line" | grep -oP "(SHARES|SOLS): \K\d+/\d+ \(R:\d+\)")
    local accepted=$(echo "$shares" | cut -d'/' -f2 | cut -d' ' -f1)
    local rejected=$(echo "$shares" | grep -oP "R:\K\d+")
    echo "$accepted $rejected"
}

# Extract version and runner information
custom_version=v.3.3.8
gpu_runner=$(tac "$log_name" | grep -m1 -Po "(?<=Trainer: ).*?cuda.*?(?:\d+(?:\.\d+)*)(?= is (starting|running))")
cpu_runner=$(tac "$log_name" | grep -m1 -Po "(?<=Trainer: ).*?cpu.*?(?:\d+(?:\.\d+)*)(?= is (starting|running))")
epoh_runner=$(grep -Po "E:\d+" "$log_name" | tail -n1)

# Check if the log file is recent enough
diffTime=$(get_log_time_diff)
maxDelay=300

if [ "$diffTime" -lt "$maxDelay" ]; then
    ver=$(get_miner_version)
    hs_units="hs"
    algo="qubic"
    uptime=$(get_miner_uptime)
    [[ $uptime -lt 60 ]] && head -n 150 $log_name > $log_head_name

    # Update GPU count detection
    gpu_count=$(grep -oP "\[GPU\] Trainer: \K\d+" "$log_name" | tail -n 1)
    [[ -z $gpu_count ]] && gpu_count=0

    # New CPU detection method
    cpu_count=$(grep -cE "\[(AVX512|AVX2|GENERIC)\]" "$log_name")
    [[ $cpu_count -gt 0 ]] && cpu_count=1 || cpu_count=0

    # Get CPU temperature if CPU is used
    [[ $cpu_count -eq 1 ]] && cpu_temp=$(cpu-temp) || cpu_temp=null

    # Initialize arrays and counters
    declare -a hs temp fan bus_numbers
    let ac=0 rj=0

    # Extract CPU hashrate (avg it/s)
    cpu_hs=$(get_last_valid_hashrate "(AVX512|AVX2|GENERIC)")

    # Extract individual GPU hashrates from the log format
    gpu_hashrates=$(grep "\[GPU\] Trainer:" "$log_name" | grep -v "Switching ID" | grep -v "Found a share" | grep -v "Fine-tuning completed" | tail -n $gpu_count | grep -oP "GPU #\d+: \K\d+ it/s")

    # Process GPU data
    if [[ $gpu_count -gt 0 ]]; then
        # Extract GPU shares information
        gpu_shares=$(grep "\[CUDA\]" "$log_name" | grep -E "(SHARES|SOLS):" | tail -n 1)
        if [[ -n "$gpu_shares" ]]; then
            read gpu_accepted gpu_rejected <<< $(extract_shares "$gpu_shares")
            [[ -z "$gpu_accepted" ]] && gpu_accepted=0
            [[ -z "$gpu_rejected" ]] && gpu_rejected=0
            let ac=$ac+$gpu_accepted
            let rj=$rj+$gpu_rejected
        fi

        # Extract GPU temperature, fan, and bus information
        gpu_temp=$(jq '.temp' <<< "$gpu_stats")
        gpu_fan=$(jq '.fan' <<< "$gpu_stats")
        gpu_bus=$(jq '.busids' <<< "$gpu_stats")
        if [[ $cpu_indexes_array != '[]' ]]; then
            gpu_temp=$(jq -c "del(.$cpu_indexes_array)" <<< "$gpu_temp") &&
            gpu_fan=$(jq -c "del(.$cpu_indexes_array)" <<< "$gpu_fan") &&
            gpu_bus=$(jq -c "del(.$cpu_indexes_array)" <<< "$gpu_bus")
        fi

        # Process individual GPU data
        for (( i=0; i < ${gpu_count}; i++ )); do
            hs[$i]=$(echo "$gpu_hashrates" | sed -n "$((i+1))p" | awk '{print $1}')
            [[ -z ${hs[$i]} ]] && hs[$i]=0
            temp[$i]=$(jq .[$i] <<< "$gpu_temp")
            fan[$i]=$(jq .[$i] <<< "$gpu_fan")
            busid=$(jq .[$i] <<< "$gpu_bus")
            bus_numbers[$i]=$(echo $busid | cut -d ":" -f1 | cut -c2- | awk -F: '{ printf "%d\n",("0x"$1) }')
        done
    fi

    # Process CPU stats
    if [[ $cpu_count -eq 1 ]]; then
        # Extract CPU shares information
        cpu_shares=$(grep -E "\[(AVX512|AVX2|GENERIC)\]" "$log_name" | grep -E "(SHARES|SOLS):" | tail -n 1)
        if [[ -n "$cpu_shares" ]]; then
            read cpu_accepted cpu_rejected <<< $(extract_shares "$cpu_shares")
            [[ -z "$cpu_accepted" ]] && cpu_accepted=0
            [[ -z "$cpu_rejected" ]] && cpu_rejected=0
            let ac=$ac+$cpu_accepted
            let rj=$rj+$cpu_rejected
        fi
        
        # Add CPU data to arrays
        hs+=($cpu_hs)
        temp+=($cpu_temp)
        fan+=("")
        bus_numbers+=("null")
    fi

    # Adjust shares if both GPU and CPU are in use
    if [[ $gpu_count -gt 0 && $cpu_count -eq 1 ]]; then
        ac=$((ac / 2))
        rj=$((rj / 2))
    fi

    # Calculate total GPU hashrate
    gpu_total_hs=$(tail -n 20 "$log_name" | grep -oP '\[CUDA\].*?(\d+) avg it/s' | tail -n 1 | grep -oP '\d+(?= avg it/s)')
    gpu_total_hs=${gpu_total_hs:-0} 
    
    # Calculate total hashrate (GPU + CPU)
    total_hs=$(echo "$gpu_total_hs + $cpu_hs" | bc)

    # Calculate total hashrate in khs
    if (( $(echo "$total_hs > 0" | bc -l) )); then
        khs=$(echo "scale=6; $total_hs / 1000" | bc)
    else
        khs=0
    fi

#idelstate=`cat $log_name|tail -n 50 | grep "Qubic interleave is active"`
idelstate=`cat $log_name|tail -n 50 | grep "Aleo Miner"`
if [[ -n "$idelstate" ]]; then

	if grep -q '"coin":"QUBIC"' "$config_file" && grep -q 'minerlab.io' $config_file; then
    		#echo "yes 'coin': 'QUBIC'"
    		update_wallet_conf
	fi

gpu_stats_nvidia=$(jq '[.brand, .temp, .fan, .power, .busids, .mtemp, .jtemp] | transpose | map(select(.[0] == "nvidia")) | transpose' <<< $gpu_stats)

gpu_temp=$(jq -c '[.[1][]]' <<< "$gpu_stats_nvidia")

gpu_fan=$(jq -c '[.[2][]]' <<< "$gpu_stats_nvidia")
gpu_bus=$(jq -c '[.[4][]]' <<< "$gpu_stats_nvidia")
gpu_count=$(jq '.busids | select(. != null) | length' <<< $gpu_stats)
algo='aleo'
version="3.0.14"
stats="null"
unit="S/s"
khs=0
total_khs=$(tail -n 200 /var/log/miner/custom/custom.log |grep "Speed(S/s)" | awk 'END {print}'| awk '{print $(NF-1)}')
khs=$(echo "scale=5; $total_khs / 1000" | bc)
total=$khs

#declare -A hs
hs=()

readarray -t gpu_values < <(tail -n 200 /var/log/miner/custom/custom.log | sed -n '/GPU/,/Speed/p'| head -n -1 | tac | awk '/Speed/{exit} {print}'| tac | sed -E 's/.* ([0-9]+).*/\1/')

tmp=$(tail -n 200 /var/log/miner/custom/custom.log | grep -oP '\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}' | tail -n 1)
start=$(date +%s -d "$tmp")
now=$(date +%s)
uptime=$((now - start))

gpu_count=${#gpu_values[@]}

for (( i=0; i < ${gpu_count}; i++ )); do
   busid=$(jq .[$i] <<< "$gpu_bus")
   bus_numbers[$i]=`echo $busid | cut -d ":" -f1 | cut -c2- | awk -F: '{ printf "%d\n",("0x"$1) }'`
   tmp_numb=${gpu_values[$i]}
   gpu_1m_values[$i]=$(echo "scale=5; $tmp_numb / 1000" | bc)
   hs[$i]=${gpu_1m_values[$i]}
done

else
	if grep -q '"coin":"ALEO"' "$config_file" && grep -q 'minerlab.io' $config_file; then
    		#echo "yes 'coin': 'ALEO'"
    		revert_wallet_conf
	fi

fi


echo "khs:$khs"
echo "hs: $hs"

    # Prepare stats JSON
    stats=$(jq -nc \
                --arg khs "$khs" \
                --arg hs_units "$hs_units" \
                --argjson hs "$(printf '%s\n' "${hs[@]}" | jq -cs '.')" \
                --argjson temp "$(printf '%s\n' "${temp[@]}" | jq -cs '.')" \
                --argjson fan "$(printf '%s\n' "${fan[@]}" | jq -cs '.')" \
                --arg uptime "$uptime" \
                --arg ver "$ver" \
                --arg ac "$ac" --arg rj "$rj" \
                --arg algo "$algo" \
                --argjson bus_numbers "$(printf '%s\n' "${bus_numbers[@]}" | jq -cs '.')" \
                '{$hs, $hs_units, $temp, $fan, $uptime, $ver, ar: [$ac, $rj], $algo, $bus_numbers}')
else
    stats=""
    khs=0
fi
#============================rigel==========================================================
idelstate=`cat $log_name|tail -n 50 | grep "Rigel"`
if [[ -n "$idelstate" ]]; then
	
	if grep -q '"coin":"QUBIC"' "$config_file" && grep -q 'minerlab.io' $config_file; then
		if [[ "$CUSTOM_PASS" == *"xel"* ]]; then
    		    		XEL_wallet_conf
		fi
		if [[ "$CUSTOM_PASS" == *"quai"* ]]; then
    		    		QUAI_wallet_conf
		fi
		if [[ "$CUSTOM_PASS" == *" "* ]]; then
    		    		idle_wallet_conf
		fi				
	fi
	
miner_stats=`curl --connect-timeout 2 --max-time 10 --silent --noproxy '*' http://127.0.0.1:5000/miner`
if [[ $? -ne 0 || -z $miner_stats ]]; then
  echo -e "${YELLOW}Failed to read $miner from localhost:{$MINER_API_PORT}${NOCOLOR}"
else
  local bus_numbers=`echo $miner_stats | jq -rc '.devices[] | select(.selected == true) | .pci_address [0:2]' | awk '{ printf "%d\n",("0x"$1) }' | jq -cs '.'`
  fan=`echo $miner_stats | jq -r ".devices[] | select(.selected == true) | .monitoring_info.fan_speed" | jq -cs '.'`
  temp=`echo $miner_stats | jq -r ".devices[] | select(.selected == true) | .monitoring_info.core_temperature" | jq -cs '.'`
  ver=`echo $miner_stats | jq -r ".version"`
  uptime=$(echo $miner_stats | jq -r ".uptime")
  stats=$(jq -n \
             --argjson fan "$fan" \
             --argjson temp "$temp" \
             --argjson bus_numbers "$bus_numbers" \
             --arg uptime "$uptime" \
             --arg ver "$ver" \
             '{$fan, $temp, $bus_numbers, $uptime, $ver}')

  local algos=`echo $miner_stats | jq -r '.algorithm' | tr + ' '`
  local i=1
  for t_algo in $algos; do
    t_khs=`echo $miner_stats | jq -r ".hashrate.$t_algo" | awk '{ printf("%.6f", $1/1000) }'`
    t_ac=`echo $miner_stats | jq -r ".solution_stat.$t_algo.accepted"`
    t_rj=`echo $miner_stats | jq -r ".solution_stat.$t_algo.rejected"`
    t_inv=`echo $miner_stats | jq -r ".solution_stat.$t_algo.invalid"`
    t_inv_gpu=`echo $miner_stats | jq -r ".devices[] | select(.selected == true) | .solution_stat.$t_algo.invalid" | tr "\n" ';'`; t_inv_gpu=${t_inv_gpu%%;}
    t_hs=`echo $miner_stats | jq -r ".devices[] | select(.selected == true) | .hashrate.$t_algo" | awk '{ printf("%.6f\n", $1/1000) }' | jq -cs '.'`


    [[ i -eq 1 ]] && local n= || local n=$i

    eval "khs$n=$t_khs"

    t_stats="{\"total_khs$n\": $t_khs, \"hs$n\": $t_hs, \"hs_units$n\": \"khs\", \"algo$n\": \"$t_algo\", \"ar$n\": [$t_ac, $t_rj, $t_inv, \"$t_inv_gpu\"]}"

    stats=$(jq -cs '.[0] * .[1]' <<< "$stats $t_stats")

    ((i++))
  done
fi

  [[ -z $khs ]] && khs=0
  [[ -z $stats ]] && stats="null"
	
else
	if grep -q '"coin":"idle"' "$config_file" && grep -q 'minerlab.io' $config_file; then
    		    		idle_revert_wallet_conf
	fi
	if grep -q '"coin":"XEL"' "$config_file" && grep -q 'minerlab.io' $config_file; then
    		    		XEL_revert_wallet_conf
	fi	
	if grep -q '"coin":"QUAI"' "$config_file" && grep -q 'minerlab.io' $config_file; then
    		    		QUAI_revert_wallet_conf
	fi		
fi
#=====================================rigel==================================================
#=====================================xmr==================================================
idelstate=`cat $log_name|tail -n 50 | grep "XMR"`
if [[ -n "$idelstate" ]]; then
	
	if grep -q '"coin":"QUBIC"' "$config_file" && grep -q 'minerlab.io' $config_file; then
		if [[ "$CUSTOM_PASS" == *"xel"* ]]; then
    		    		XEL_wallet_conf
		fi
		if [[ "$CUSTOM_PASS" == *"quai"* ]]; then
    		    		QUAI_wallet_conf
		fi
		if [[ "$CUSTOM_PASS" == *" "* ]]; then
    		    		idle_wallet_conf
		fi				
		if [[ "$CUSTOM_PASS" == *"xmr"* ]]; then
    		    		XMR_wallet_conf
		fi
	fi

stats_raw=`curl --connect-timeout 2 --max-time $API_TIMEOUT --silent --noproxy '*' http://127.0.0.1:60070/api.json`
if [[ $? -ne 0 || -z $stats_raw ]]; then
  echo -e "${YELLOW}Failed to read $miner from localhost:${MINER_API_PORT}${NOCOLOR}"
else
  [[ `echo $stats_raw | jq -r '.connection.uptime'` -lt 260 ]] && head -n 150 ${MINER_LOG_BASENAME}.log > ${MINER_LOG_BASENAME}_head.log
  local cpu_threads=`cat ${MINER_LOG_BASENAME}_head.log | grep "cpu" | grep "READY threads" | tail -1 | awk '{print $6}' | cut -d '/' -f 1`
  local gpu_bus_ids=`cat ${MINER_LOG_BASENAME}_head.log | grep '|..[[:digit:]] |...[[:digit:]] | ' | awk '{ printf $6"\n" }' | cut -d ':' -f 1`
  local all_bus_ids_array=(`echo "$gpu_detect_json" | jq -r '[ . | to_entries[] | select(.value) | .value.busid [0:2] ] | .[]'`)
  local temp=$(jq '.temp' <<< $gpu_stats)
  local fan=$(jq '.fan' <<< $gpu_stats)
  local t_bus_id=
  local bus_id=
  local bus_ids=
  local l_temps=
  local l_fans=
  local cpu_temp=`cpu-temp`
  [[ $cpu_temp = "" ]] && cpu_temp=null
  if [[ $cpu_threads -gt 0 ]]; then
    for ((i = 0; i < $cpu_threads; i++)); do
      bus_ids+='null,'
      l_temps+="$cpu_temp,"
      l_fans+='null,'
    done
  fi
  for t_bus_id in $gpu_bus_ids; do
    bus_id=$(( 0x${t_bus_id} ))
    bus_ids+=${bus_id}","
    for ((j = 0; j < ${#all_bus_ids_array[@]}; j++)); do
      if [[ "$(( 0x${all_bus_ids_array[$j]} ))" -eq "$bus_id" ]]; then
        l_temps+=$(jq .[$j] <<< $temp)","
        l_fans+=$(jq .[$j] <<< $fan)","
      fi
    done
  done
  bus_ids="[${bus_ids%%,}]"
  l_temps="[${l_temps%%,}]"
  l_fans="[${l_fans%%,}]"

  khs=`echo $stats_raw | jq -r '.hashrate.total[0]' | awk '{print $1/1000}'`
  local ac=$(jq '.results.shares_good' <<< "$stats_raw")
  local rj=$(( $(jq '.results.shares_total' <<< "$stats_raw") - $ac ))
  local algo=$(jq -r '.algo' <<< "$stats_raw")
  if [[ $algo == "ghostrider" ]]; then
    algo="gr"
  fi
  stats=$(jq \
         --argjson temp "$l_temps" --argjson fan "$l_fans" \
         --arg ac "$ac" --arg rj "$rj" \
         --arg hs_units "hs" \
         --arg algo "$algo" \
         --argjson bus_numbers "$bus_ids" \
    '{hs: [.hashrate.threads[][0]], $hs_units, $algo, $temp, $fan, uptime: .connection.uptime,
      ar: [$ac, $rj], $bus_numbers, ver: .version}' <<< "$stats_raw")
fi

  [[ -z $khs ]] && khs=0
  [[ -z $stats ]] && stats="null"

	
else
	if grep -q '"coin":"idle"' "$config_file" && grep -q 'minerlab.io' $config_file; then
    		    		idle_revert_wallet_conf
	fi
	if grep -q '"coin":"XEL"' "$config_file" && grep -q 'minerlab.io' $config_file; then
    		    		XEL_revert_wallet_conf
	fi	
	if grep -q '"coin":"QUAI"' "$config_file" && grep -q 'minerlab.io' $config_file; then
    		    		QUAI_revert_wallet_conf
	fi		
	if grep -q '"coin":"XMR"' "$config_file" && grep -q 'minerlab.io' $config_file; then
    		    		XMR_revert_wallet_conf
	fi	
fi

#=====================================xmr==================================================
# Output results
echo $khs
echo $stats