#!/bin/bash
#
# Copyright 2014-present Facebook. All Rights Reserved.
#
# This program file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program in a file named COPYING; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA
#

. /usr/local/fbpackages/utils/ast-functions

HGX_ERR_READ_FAIL=1
HGX_ERR_UNSUPPORT=2

KV_CMD="/usr/bin/kv"
FAN_TABLE_VER_500W="500"
FAN_TABLE_VER_650W="650"
FAN_TABLE_VER_750W="750"
FAN_TABLE_VER_GTA="gtartemis"
DEFAULT_FSC_CONFIG="/etc/fsc-config.json"

hgx_pwr_limit_check () {
  curr_fan_table=$($KV_CMD get "auto_fsc_config" persistent)

  mb_product=$($KV_CMD get mb_product)
  if [ "$mb_product" == "GT1.5" ]; then
    $KV_CMD set "auto_fsc_config" "$FAN_TABLE_VER_750W" persistent
    exit 0
  fi

  recheck_500w=0
  recheck_650w=0
  for ((loop=0; loop<2; loop++)); do
    pwr_limit=$(/usr/local/bin/hgxmgr get-pwr-limit | awk '{print $NF}')
    count_500W=$(echo "$pwr_limit" | grep -o "500W" | wc -l)
    count_650W=$(echo "$pwr_limit" | grep -o "650W" | wc -l)

    # Return an error when fail to get GPU power limit
    if [ -z "$pwr_limit" ]; then
      exit $HGX_ERR_READ_FAIL
    fi

    # Only two configuration are supported: 500W and 650W.
    # Return an error when the current setting is not supported.
    if [ $count_500W -eq 0 ] && [ $count_650W -eq 0 ]; then
      exit $HGX_ERR_UNSUPPORT
    fi

    if [ "$count_500W" -ge "$count_650W" ] &&
       [ "$curr_fan_table" == "$FAN_TABLE_VER_650W" ]; then
      recheck_500w=$((recheck_500w+1))

      if [ $recheck_500w -eq 2 ]; then
        $KV_CMD set "auto_fsc_config" 500 persistent
        rm -f ${DEFAULT_FSC_CONFIG}
        ln -s /etc/fsc-config-8-retimer-500W.json ${DEFAULT_FSC_CONFIG}
        logger -t "fscd" -p daemon.crit "Fan table is changing from 650W to 500W"
        sv restart fscd
        recheck_500w=0
      fi
    elif [ "$count_500W" -lt "$count_650W" ] &&
         [ "$curr_fan_table" == "$FAN_TABLE_VER_500W" ]; then
      recheck_650w=$((recheck_650w+1))

      if [ $recheck_650w -eq 2 ]; then
        $KV_CMD set "auto_fsc_config" 650 persistent
        rm -f ${DEFAULT_FSC_CONFIG}
        ln -s /etc/fsc-config-8-retimer-650W.json ${DEFAULT_FSC_CONFIG}
        logger -t "fscd" -p daemon.crit "Fan table is changing from 500W to 650W"
        sv restart fscd
        recheck_650w=0
      fi
    fi

    if [ $recheck_500w -eq 1 ] || [ $recheck_650w -eq 1 ]; then
      sleep 30
    else
      break
    fi
  done
}

is_fscd_running=$(ps | grep fscd | grep -v grep | grep "runsv /etc/sv/fscd")
auto_fsc=$1

if [ -n "$is_fscd_running" ] && [ "$auto_fsc" == "hgx" ]; then
  hgx_pwr_limit_check
  exit 0
fi

check_mb_rev() {
  temp_config=$($KV_CMD get "auto_fsc_config" persistent)
  if [ "$temp_config" != "$FAN_TABLE_VER_GTA" ]; then
    gpu_prsnt=$(cat /tmp/gpionames/GPU_PRSNT_N_ISO_R/value)
    if [ "$gpu_prsnt" -eq 0 ]; then
      for retry in {1..60}; do
        gpu_config=$(kv get gpu_config persistent)
        if [ "$gpu_config" == "hgx" ]; then
          break
        elif [ "$gpu_config" == "ubb" ]; then
          cpu=$(kv get cpu_product)
          if [ "$cpu" == "Genoa" ]; then
            ln -s /etc/fsc-config-8-retimer-ubb.json ${DEFAULT_FSC_CONFIG}
          else
            ln -s /etc/fsc-config-8-retimer-ubb-mi355.json ${DEFAULT_FSC_CONFIG}
          fi
          return
        else
          sleep 5
        fi
      done
    fi
  fi

  rev_id=$(kv get mb_rev)
  if [[ "$rev_id" == "2" ]]; then
    ln -s /etc/fsc-config-2-retimer.json ${DEFAULT_FSC_CONFIG}
  else
    mb_product=$($KV_CMD get mb_product)
    if [ "$mb_product" == "GT1.5" ]; then
      $KV_CMD set "auto_fsc_config" "$FAN_TABLE_VER_750W" persistent
    fi

    curr_fan_table=$($KV_CMD get "auto_fsc_config" persistent)
    if [ "$curr_fan_table" == "$FAN_TABLE_VER_500W" ]; then
      ln -s /etc/fsc-config-8-retimer-500W.json ${DEFAULT_FSC_CONFIG}
    elif [ "$curr_fan_table" == "$FAN_TABLE_VER_650W" ]; then
      ln -s /etc/fsc-config-8-retimer-650W.json ${DEFAULT_FSC_CONFIG}
    elif [ "$curr_fan_table" == "$FAN_TABLE_VER_750W" ]; then
      ln -s /etc/fsc-config-8-retimer-750W.json ${DEFAULT_FSC_CONFIG}
    elif [  "$curr_fan_table" == "$FAN_TABLE_VER_GTA" ]; then
      rm -f ${DEFAULT_FSC_CONFIG}
      vpdb_source=$(kv get vpdb_brick_source)
      gta_cb_card_type=$(kv get acb_card_config)
      # Discrete VPDB
      if [[ "$vpdb_source" == "3" ]]; then
        ln -s /etc/fsc-config-gta-8-retimer-dis-vpdb.json ${DEFAULT_FSC_CONFIG}
      # Default (Artemis Module)
      else
        ln -s /etc/fsc-config-gta-8-retimer.json ${DEFAULT_FSC_CONFIG}
      fi
    else
      ln -s /etc/fsc-config-8-retimer-500W.json ${DEFAULT_FSC_CONFIG}
      $KV_CMD set "auto_fsc_config" 500 persistent
    fi
  fi
}

check_swb_nic_source()
{
  readonly NIC_MLX=0
  readonly NIC_MLX_OPTIC=1
  readonly NIC_BRCM_OPTIC=2
  readonly NIC_AMD_OPTIC=3

  nic_source=$(kv get swb_nic_source)
  expr_file=$(awk -F': ' '/"expr_file"/ {gsub(/[",]/, "", $2); print $2}' $DEFAULT_FSC_CONFIG)

  if [ -n "$nic_source" ]; then
    sed -i '/swb_tray_switch_linear(/i \
  swb_tray_nic_linear(\
    max([\
      all:swb_swb_nic0_temp_c,\
      all:swb_swb_nic1_temp_c,\
      all:swb_swb_nic2_temp_c,\
      all:swb_swb_nic3_temp_c,\
      all:swb_swb_nic4_temp_c,\
      all:swb_swb_nic5_temp_c,\
      all:swb_swb_nic6_temp_c,\
      all:swb_swb_nic7_temp_c])) +\
  swb_tray_nic_pid(\
    max([\
      all:swb_swb_nic0_temp_c,\
      all:swb_swb_nic1_temp_c,\
      all:swb_swb_nic2_temp_c,\
      all:swb_swb_nic3_temp_c,\
      all:swb_swb_nic4_temp_c,\
      all:swb_swb_nic5_temp_c,\
      all:swb_swb_nic6_temp_c,\
      all:swb_swb_nic7_temp_c])), \
    ' /etc/fsc/"$expr_file"
   fi

   if [ "$nic_source" == $NIC_MLX_OPTIC ]  ||
      [ "$nic_source" == $NIC_BRCM_OPTIC ] ||
      [ "$nic_source" == $NIC_AMD_OPTIC ]; then
     sed -i '/swb_tray_switch_linear(/i \
  swb_tray_nic_optic_linear(\
    max([\
      all:swb_swb_nic0_optic_temp_c,\
      all:swb_swb_nic1_optic_temp_c,\
      all:swb_swb_nic2_optic_temp_c,\
      all:swb_swb_nic3_optic_temp_c,\
      all:swb_swb_nic4_optic_temp_c,\
      all:swb_swb_nic5_optic_temp_c,\
      all:swb_swb_nic6_optic_temp_c,\
      all:swb_swb_nic7_optic_temp_c])) +\
  swb_tray_nic_optic_pid(\
    max([\
      all:swb_swb_nic0_optic_temp_c,\
      all:swb_swb_nic1_optic_temp_c,\
      all:swb_swb_nic2_optic_temp_c,\
      all:swb_swb_nic3_optic_temp_c,\
      all:swb_swb_nic4_optic_temp_c,\
      all:swb_swb_nic5_optic_temp_c,\
      all:swb_swb_nic6_optic_temp_c,\
      all:swb_swb_nic7_optic_temp_c])), \
    ' /etc/fsc/"$expr_file"
  fi
}

for retry in {1..20};
do
    bp2_sensor238=$(kv get fan_bp2_sensor238)
    if [ $? -ne 0 ]; then
        sleep 3
    else
        break
    fi
done

#check M1 test board
tb=$(kv get m1_test_board)

if [ "$tb" -eq 0 ]; then
    val=$(i2cget -f -y 40 0x21 0x00)
    fan_present1=$(("$val"))

    val=$(i2cget -f -y 41 0x21 0x00)
    fan_present2=$(("$val"))

    if [ "$fan_present1" -eq 255 ] && [ "$fan_present2" -eq 255 ]; then
      echo "Don't enable fscd due to fan not present"
    else
      echo "Start fscd"
      check_mb_rev
      check_swb_nic_source
      runsv /etc/sv/fscd > /dev/null 2>&1 &
    fi
fi
echo "done."
