#!/bin/sh
#
#    Copyright (c) 1996-2006 Brocade Communications Systems, Inc.
#    All rights reserved.
#
#
# NAME
#      diagsetcycle - set diagnostic script parameters
# 
# SYNOPSIS
#      diagsetcycle [script | -current ] [ -show | -default | [ -keyword value
#      ... ]]
# 
# AVAILABILITY
#      admin
# 
# DESCRIPTION
#      This command provides interactive way of updating diagnostic
#      command parameters. With only script specified, it will dis-
#      play all  configuration  variables  used  by  the  specified
#      script  and  go  into an interactive session. Using the full
#      stretched option parameters, variables can be  updated  non-
#      interactively too.
# 
#      In  interactive  mode, the current value, default value, and
#      description of purpose of the  variable  are  displayed  for
#      each  variable.  If no new value is specified, then the cur-
#      rent value is left unchanged. If a  new  value  is  entered,
#      then  its  value is updated, and stored in the configuration
#      database for that blade type. It does not require  a  reboot
#      to take effect.
# 
# OPTIONS
#      script    Specify which script's prameters to edit.
# 
#      -current  It  will use the currently selected burnin script.
# 
#      -show     It  will  display  the parameters for a diagnostic
#                script specified by script.
# 
#      -default  The script parameters will be set to default  val-
#                ues.
# 
#      -keyword value
#                The  script parameters can be updated non-interac-
#                tively using this style of option list. keyword is
#                the  keyword  to  update  and  the value should be
#                specified manually in this case.
# 
# EXAMPLES
#      > diagsetcycle switchburnin.sh -show
#      CURRENT - KEYWORD        : DEFAULT
#       1      - number_of_runs : 1
#       2      - vib            : 2
#       10     - thermal        : 10
#       BURNIN - label          : BURNIN
#       1      - tbr_passes     : 1
#       1      - prt_on         : 1
#       1      - cntmem_on      : 1
#       1      - cmi_on         : 1
#       1      - retention_on   : 1
#       1      - cam_on         : 1
#       50     - flt_passes     : 50
#       25     - sta_passes     : 25
#       100    - plb_nframes    : 100
#       50     - txd_nframes    : 50
#       200    - xpt_nframes    : 200
#       20     - bpt_nframes    : 20
#       50     - slk_nmegs      : 50
#       30     - bpt_all_nframes: 30
#       50     - slk_all_nmegs  : 50
# 
# SEE ALSO
#      burninname(1d), burninlevel(1d), burninscript(1d),  diagset-
#      burnin(1d), diagstopburnin(1d)
# 

##################################
# This function diagsetcycledefault() is for library use only.
# It processes each PARAMDEF variable, and sets each variable
# to the default value for each parameter. The config database
# is updated only if a value is modified values. If values are 
# not found in the config database, entries are inserted with 
# the default values.
#
# The format of the PARAMDEF is inturpeted as follows:
# $1 = space seperated PARAMDEF
# Field Description
# 1     PARAMDEF
# 2     Variable name
# 3     Default value for named variable
# 4     Mode of the variable ($INTEGER, $STRING)
# 5     Minimum valid value of named variable (NA if not applicable)
# 6     Maximum valid value of named variable (NA if not applicable)
# 7     Description of the effect of the named variable
#
# The configdata base is queried to determine 
# the current value. If the entry does not exist, then an 
# entry is created with the default value. The user is queried 
# for modification and the value is updated if it is not the default.
##################################
diagsetcycledefault()
{
  /bin/echo "DEFAULT	- KEYWORD	: COMMENT"
  _num=1
  while [ $_num -le $_num_params ]
  do
    _param=`/bin/echo $_param_list | /usr/bin/cut -d"@" -f$_num`
    _var_name=`/bin/echo $_param | /usr/bin/cut -d" " -f2`
    _dflt_val=`/bin/echo $_param | /usr/bin/cut -d" " -f3`
    _mode_val=`/bin/echo $_param | /usr/bin/cut -d" " -f4`
    _cmnt=`/bin/echo $_param     | /usr/bin/cut -d" " -f7-`
    _cur_val="`get_config_entry $_var_name`"
    if [ $_dflt_val != "$_cur_val" ]
    then
      /bin/echo replacing $_cur_val with default $_dflt_val
      setConfig diag.$MyName.$_var_name $_mode_val "$_dflt_val"
      _modified=TRUE
    fi
    /bin/echo " $_dflt_val	- $_var_name	: $_cmnt "
    _num=`/usr/bin/expr $_num + 1`
  done
  _num=1
  while [ $_num -le $_num_consts ]
  do
    _param=`/bin/echo $_const_list | /usr/bin/cut -d"@" -f$_num`
    _var_name=`/bin/echo $_param | /usr/bin/cut -d" " -f2`
    _dflt_val=`/bin/echo $_param | /usr/bin/cut -d" " -f3`
    _mode_val=`/bin/echo $_param | /usr/bin/cut -d" " -f4`
    _cmnt=`/bin/echo $_param     | /usr/bin/cut -d" " -f7-`
    _cur_val="`get_config_entry $_var_name`"
    if [ $_dflt_val != "$_cur_val" ]
    then
      setConfig diag.$MyName.$_var_name $_mode_val "$_dflt_val"
      _modified=TRUE
    fi
    _num=`/usr/bin/expr $_num + 1`
  done
  config_list=`get_config_list`
}

##################################
# This function diagsetcycleshort() is for library use only.
# It processes each PARAMDEF variable, and sets each variable
# to the short value for each parameter. The config database
# is updated only if a value is modified values. If values are 
# not found in the config database, entries are inserted with 
# the default values. The "short" value is contained in the flags
# field with the keyword value pair "S:value".
#
# The format of the PARAMDEF is inturpeted as follows:
# $1 = space seperated PARAMDEF
# Field Description
# 1     PARAMDEF
# 2     Variable name
# 3     Default value for named variable
# 4     Mode of the variable ($INTEGER, $STRING)
# 5     Minimum valid value of named variable (NA if not applicable)
# 6     Maximum valid value of named variable (NA if not applicable)
# 7     Description of the effect of the named variable
#
# The configdata base is queried to determine 
# the current value. If the entry does not exist, then an 
# entry is created with the default value. The user is queried 
# for modification and the value is updated if it is not the default.
##################################
diagsetcycleshort()
{
  _num=1
  while [ $_num -le $_num_params ]
  do
    _param=`/bin/echo $_param_list | /usr/bin/cut -d"@" -f$_num`
    _flags=`/bin/echo $_param | /usr/bin/cut -d" " -f1`
    _var_name=`/bin/echo $_param | /usr/bin/cut -d" " -f2`
    _dflt_val=`/bin/echo $_param | /usr/bin/cut -d" " -f3`
    _mode_val=`/bin/echo $_param | /usr/bin/cut -d" " -f4`
    _cmnt=`/bin/echo $_param     | /usr/bin/cut -d" " -f7-`
    _cur_val="`get_config_entry $_var_name`"
    if [ "`/bin/echo $_flags | grep S`" != "" ]
    then
      _short_val=0
      for pair in `/bin/echo "$_flags" | /bin/sed "s/,/ /g"`
      do
        if [ "`/bin/echo $pair | /bin/grep S`" != "" ]
        then
          _short_val=`/bin/echo $pair | /usr/bin/cut -d":" -f2`
          break
        fi
      done
      if [ $_short_val != "$_cur_val" ]
      then
        /bin/echo "  Replacing current value $_cur_val with $_short_val for variable $_var_name."
        setConfig diag.$MyName.$_var_name $_mode_val "$_short_val"
        _modified=TRUE
      fi
    fi
    _num=`/usr/bin/expr $_num + 1`
  done
  config_list=`get_config_list`
}

##################################
# This function diagsetcycleshow() is for library use only.
# It processes each PARAMDEF variable, and outputs the current
# setting for each variable. The config database is used to 
# get the current setting. If values are not found in the config
# database, the default value is output.
#
# The format of the PARAMDEF is inturpeted as follows:
# $1 = space seperated PARAMDEF
# Field Description
# 1     PARAMDEF
# 2     Variable name
# 3     Default value for named variable
# 4     Mode of the variable ($INTEGER, $STRING)
# 5     Minimum valid value of named variable (NA if not applicable)
# 6     Maximum valid value of named variable (NA if not applicable)
# 7     Description of the effect of the named variable
##################################
diagsetcycleshow()
{
  /bin/echo "CURRENT - KEYWORD          : DEFAULT "
  _num=1
  while [ $_num -le $_num_params ]
  do
    _param=`/bin/echo $_param_list | /usr/bin/cut -d"@" -f$_num`
    _var_name=`/bin/echo $_param | /usr/bin/cut -d" " -f2`
    _dflt_val=`/bin/echo $_param | /usr/bin/cut -d" " -f3`
    _mode_val=`/bin/echo $_param | /usr/bin/cut -d" " -f4`
    _cmnt=`/bin/echo $_param     | /usr/bin/cut -d" " -f7-`
    _cur_val="`get_config_entry $_var_name`"
    if [ -z "$_cur_val" ]
    then
      _cur_val=$_dflt_val
    fi
    printf "%-7s - %-16s : %s\n" "$_cur_val" "$_var_name" "$_dflt_val"
    _num=`/usr/bin/expr $_num + 1`
  done
}

##################################
# This function diagsetcycleinteractive() is for library use only.
# It processes each PARAMDEF variable, and asks user for new 
# value for each parameter. The config database is updated with
# the modified values. If values are not found in the config 
# database, entries are inserted with the default values.
#
# The format of the PARAMDEF is inturpeted as follows:
# $1 = space seperated PARAMDEF
# Field Description
# 1     PARAMDEF
# 2     Variable name
# 3     Default value for named variable
# 4     Mode of the variable ($INTEGER, $STRING)
# 5     Minimum valid value of named variable (NA if not applicable)
# 6     Maximum valid value of named variable (NA if not applicable)
# 7     Description of the effect of the named variable
#
# The configdata base is queried to determine 
# the current value. If the entry does not exist, then an 
# entry is created with the default value. The user is queried 
# for modification and the value is updated based on the response.
#
# If the value is outside of the min/max limits, the user is 
# re-prompted for the value. If there have been three unsuccessful 
# attempts to modify the value, then the default value is taken, 
# and the next file is processed.
##################################
diagsetcycleinteractive()
{
  /bin/echo "CURRENT - KEYWORD	- DEFAULT	, COMMENT: "
  _num=1
  while [ $_num -le $_num_params ]
  do
    _param=`/bin/echo $_param_list | /usr/bin/cut -d"@" -f$_num`
    _var_name=`/bin/echo $_param | /usr/bin/cut -d" " -f2`
    _dflt_val=`/bin/echo $_param | /usr/bin/cut -d" " -f3`
    _mode_val=`/bin/echo $_param | /usr/bin/cut -d" " -f4`
    _cmnt=`/bin/echo $_param     | /usr/bin/cut -d" " -f7-`
    _cur_val="`get_config_entry $_var_name`"
    if [ -z "$_cur_val" ]
    then
      _cur_val=$_dflt_val
      _in_config=FALSE
    else
      _in_config=TRUE
    fi
    _ok=FALSE
    _attempts=0
    while [ $_attempts -lt 3 -a $_ok != TRUE ]
    do
      /bin/echo -n " $_cur_val - $_var_name	- $_dflt_val	, $_cmnt: "
      read _answer
      _attempts=`/usr/bin/expr $_attempts + 1`
      if [ -z "$_answer" ] 
      then
        if [ "$_in_config" = "FALSE" ]
        then
          setConfig diag.$MyName.$_var_name $_mode_val $_dflt_val
          _modified=TRUE
        fi
        _ok=TRUE
      else
        if [ $_mode_val = $INTEGER ]
        then
          _min_val=`/bin/echo $_param  | /usr/bin/cut -d" " -f5`
          _max_val=`/bin/echo $_param  | /usr/bin/cut -d" " -f6`
          _ok=`validate_integer $_answer $_min_val $_max_val`
          if [ $_ok != TRUE ]
          then
            /bin/echo $_ok
            if [ $_attempts -eq 3 ]
            then
              /bin/echo " ERROR - Wrong value entered three times, using default value $_dflt_val"
              _ok=TRUE
              _answer=$_dflt_val
            else
              /bin/echo " ERROR - Invalid value. Please specify a value between $_min_val and $_max_val inclusive"
            fi
          fi
        else
          _ok=TRUE
        fi
        if [ $_ok = TRUE ]
        then
          /bin/echo " Saving new value: $_answer"
          setConfig diag.$MyName.$_var_name $_mode_val "$_answer"
          _modified=TRUE
        fi
      fi
    done
    _num=`/usr/bin/expr $_num + 1`
  done
  config_list=`get_config_list`
}

##################################
# This function diagsetcycleparameters() is for library use only.
# It processes a list of arguments from the command line, and 
# updates the config database if the PARAMDEF exists for the 
# keyword/value pair received from the command line. The config
# database is updated with the modified values. If values are
# not found in the config database and the entry appears in the
# PARAMDEF for ther script, then entries are inserted in the
# config databasewith the specified values.
#
# This function requires the arguments top be a list of files to process.
#
# The format of the PARAMDEF is inturpeted as follows:
# $1 = space seperated PARAMDEF
# Field Description
# 1     PARAMDEF
# 2     Variable name
# 3     Default value for named variable
# 4     Mode of the variable ($INTEGER, $STRING)
# 5     Minimum valid value of named variable (NA if not applicable)
# 6     Maximum valid value of named variable (NA if not applicable)
# 7     Description of the effect of the named variable
#
# If the value is outside of the min/max limits, the update will not 
# proceed.
##################################
diagsetcycleparameters()
{
  _parameters=FALSE
  i=1
  while [ "$i" -le $_num_env ]
  do
    i=`/usr/bin/expr $i + 1`
    new_param=`/bin/echo $_env | /usr/bin/cut -d"@" -f$i`
    _key=`/bin/echo $new_param | /usr/bin/cut -d" " -f1`
    _val=`/bin/echo $new_param | /usr/bin/cut -d" " -f2-`
    old_param=`get_param_list | /bin/grep -w $_key`
    if [ ! -z "$old_param" ]
    then
      _dflt_val=`/bin/echo $old_param | /usr/bin/cut -d" " -f3`
      _mode_val=`/bin/echo $old_param | /usr/bin/cut -d" " -f4`
      if [ $_mode_val = $INTEGER ]
      then
        _min_val=`/bin/echo $old_param  | /usr/bin/cut -d" " -f5`
        _max_val=`/bin/echo $old_param  | /usr/bin/cut -d" " -f6`
        _ok=`validate_integer $_val $_min_val $_max_val`
        if [ $_ok != TRUE ]
        then
          /bin/echo " ERROR - Invalid value for $_key. Value between $_min_val and $_max_val inclusive."
        else
          /bin/echo " Setting $_key to $_val."
          setConfig diag.$MyName.$_key $_mode_val "$_val"
          _modified=TRUE
        fi
      else
        /bin/echo " Setting $_key to $_val."
        setConfig diag.$MyName.$_key $_mode_val "$_val"
        _modified=TRUE
      fi
    else
      /bin/echo Could not find PARAMDEF for $_key
    fi
  done
  _num_env=0
  config_list=`get_config_list`
  _env=""
}

##################################
# This function process_diagsetcycle() is for library use only.
# It processes the remaining command line arguments, and dispatches
# work to one of four processing routines (diagsetcycledefault,
# diagsetcycleshow, diagsetcycleparameters, diagsetcycleinteractive).
#
# Each of these processing routines can be called multiple times in
# the order specified in the command line except for the interactive
# processer. The interactive is only called if no other option is
# specified.
#
# If any of the processing routines modified the content of the
# config database during their operation, the config database is 
# committed to non-volitile storage.
##################################
process_diagsetcycle()
{
  _param_list=`get_param_list`
  export _num_params=`/bin/echo $_param_list | \
         /usr/bin/tr -s " " "_" | \
         /usr/bin/tr -s "@" " " | \
         /usr/bin/wc -w`
  _const_list=`get_paramconst_list`
  export _num_consts=`/bin/echo $_const_list | \
         /usr/bin/tr -s " " "_" | \
         /usr/bin/tr -s "@" " " | \
         /usr/bin/wc -w`
  # Cache the config data base
  config_list=`get_config_list`
  _modified=FALSE
  _interactive=TRUE
  _parameters=FALSE
  if [ "$#" -ne 0 ]
  then
    _num_env=0
    shift
    _env=""
    while [ "$#" -gt 0 ]
    do
      _par=`/bin/echo $1 | /bin/sed "s/^-//g"`
      shift
      case "$_par" in 
      "default")
	if [ $_parameters = TRUE ]
        then
	  diagsetcycleparameters
        fi
        diagsetcycledefault
        _interactive=FALSE
	;;
      "short")
	if [ $_parameters = TRUE ]
	then
	  diagsetcycleparameters
	fi
	diagsetcycleshort
	_interactive=FALSE
	;;
      "show")
	if [ $_parameters = TRUE ]
        then
          diagsetcycleparameters
        fi
        diagsetcycleshow
        _interactive=FALSE
	;;
      *)  if [ $# -eq 0 ]
          then
            /bin/echo "There was no value for the keyword $_par."
          else
            _val=`/bin/echo $* | /usr/bin/cut -d"-" -f1`
            _env=`/bin/echo "$_env@$_par $_val"`
            num_args=`/bin/echo $_val | /usr/bin/wc -w`
            while [ $num_args -gt 0 ]
            do
              shift
              num_args=`/usr/bin/expr $num_args - 1`
            done
            _num_env=`/usr/bin/expr $_num_env + 1`
           _interactive=FALSE
           _parameters=TRUE
          fi;;
      esac
    done
    if [ $_interactive = TRUE ]
    then
      diagsetcycleinteractive
    fi
    if [ $_parameters = TRUE ]
    then
      diagsetcycleparameters
    fi

    if [ "$_modified" = "TRUE" ]
    then
      /bin/echo "Committing changes to configuration"
      updateConfig
    fi
  fi
  exit 0
}

###########################
# Main body of the script #
###########################
export syntax="Usage: diagSetCycle [ <script_name> | -current [ -show | -default | <-keyword value>.. ] ]\n\t -current\t Uses the current burnin script\n\t -show\t\t Outputs the values of the variables (No editing)\n\t -default\t Sets the values to the default value\n\t -keyword value\t Sets the value of a specific keyword (-number_of_runs 3)"

if [ ! $?FABOSHOME ]
then
	export FABOSHOME=/fabos
fi
home="/fabos/share"
util="diagcommon.sh"
ok=0

# a small syntax check before RBAC (def. 72243)
if [ $# -gt 0 ]; then
	# check $1 starts with "-" and it is "-current", else print usage
	firstchar=`expr substr $1 1 1`
	if [ "$firstchar" = "-" ]; then
		if [ "$1" != "-current" ]; then
			/bin/echo -e $syntax
			exit 1
		fi
	fi
fi

# perform RBAC check
if [ $# -eq 0 ]; then
    # Check RBAC permission on command
    /fabos/libexec/rbac_check `/bin/basename $0`
elif [ "$2" = "-show" ]; then
	# Check RBAC permission for actual option
	/fabos/libexec/rbac_check -opt `/bin/basename $0` $2
else
	# otherwise, just check for OPERAND_PRESENT
	/fabos/libexec/rbac_check `/bin/basename $0` $1
fi

if [ $? -ne 0 ]; then
    exit 127
fi

for f in "./$util" "$FABOSHOME/share/$util" "$home/$util"
do
  if [ -r $f ]
  then
    . $f
    ok=1
    break;
  fi
done
if [ $ok -ne 1 ]
then
  err "Could not locate $util"
  exit 3
fi
#############################
# source the parameter list #
#############################
FileName=common_test_list
util=$FileName
ok=0
for f in "./$util" "$FABOSHOME/share/$util" "$home/$util"
do
  if [ -r $f ]
  then
    . $f
    name_list=`/bin/cat $f | /usr/bin/tr -s "	 " "  " | /bin/grep "N SCRIPTNAME"| /usr/bin/cut -d " " -f3-`
    ok=1
    break;
  fi
done
if [ $ok -ne 1 ]
then
  err "Could not locate $util"
  exit 3
fi
if [ "$name_list" = "" ]
then
  err "Could not locate script name list."
  exit 3
fi

Multiblade=`isMultiBlade`
arg=""
MyName=""
if [ $# -gt 0 ]
then
	# check for a "-" character	
	if [ -z `/bin/echo $1 | /bin/sed "s/^-/@/g" | /bin/grep @` ]
	then
		MyName="$1"
		shift
	fi
	arg="$*"
fi
if [ "$1" = -current ]
then
  shift
  arg="$*"
  slots=`getAvailSlots -chassis`
  for slot in $slots
  do
    if [ -z "$MyName" ]
    then
      if [ "$Multiblade" = TRUE ]
      then
	MyName=`burninSetName -show $slot | /usr/bin/cut -d" " -f6 | /usr/bin/cut -d"." -f1-2`
      else
	MyName=`burninSetName -show $slot | /usr/bin/cut -d" " -f4 | /usr/bin/cut -d"." -f1-2`
      fi
      MyName=`/bin/echo $MyName | /bin/sed -e "s/switch//g" -e "s/\.sh//g" -e "s/\.//g"`
      MyName=`/bin/basename $MyName`
      if [ "`/bin/echo $name_list | /bin/grep -w $MyName`"  = "" -o "$MyName" = "." ]
      then
	MyName=""
	break
      fi
    else
      if [ "$Multiblade" = TRUE ]
      then
	tmpname=`burninSetName -show $slot | /usr/bin/cut -d" " -f6 | /usr/bin/cut -d"." -f1-2`
      else
	tmpname=`burninSetName -show $slot | /usr/bin/cut -d" " -f4 | /usr/bin/cut -d"." -f1-2`
      fi
      tmpname=`/bin/echo $tmpname | /bin/sed -e "s/switch//g" -e "s/\.sh//g" -e "s/\.//g"`
      tmpname=`/bin/basename $tmpname`

      if [ "$MyName" != "$tmpname" ]
      then
	MyName=""
	break
      fi
    fi
  done
fi
if [ -z "$MyName" ]
then
  /bin/echo -e $syntax
  /bin/echo "Please specify what diag cycles to set."
  match_script=""
  match=TRUE
  for _slot in $slots
  do
    current_script=`getConfig diag.mode.burnin.$_slot.name $STRING burnin`
    if [ "$match_script" = "" ]
    then
      match_script=$current_script     
    else
      if [ "$match_script" != "$current_script" ]
      then
        match=FALSE    
        break
      fi
    fi
  done
  if [ $match = TRUE ]
  then
    _num_choice=`getNumAvailableScripts -config "$name_list"`
  else
    _num_choice=`getNumAvailableScripts -noconfig "$name_list"`
  fi
  _answer=-1
  while [  $_answer -lt 0 -o $_answer -gt $_num_choice ]
  do
    /bin/echo "Choices are:"
    if [ $match = TRUE ]
    then
      showAvailableScripts "diag.mode.burnin.$_slot.name" verify "$name_list"
    else
      showAvailableScripts -noconfig "$name_list"
    fi
    /bin/echo "Make selection (0-$_num_choice)"
    read _answer
    if [ ! -z "$_answer" ]
    then
	valid=`validate_integer $_answer 0 $_num_choice`
	if [ "$valid" != "TRUE" ]
	then
	    /bin/echo "Invalid selection. valid selection are between 0 and $_num_choice"
	    /bin/echo " Please make another selection"
	    _answer=-1
	else
	    if [ $_answer -eq 0 ]
	    then
		exit 1
	    fi
          if [ $match = TRUE ]
          then
            MyName=`getScriptSelection $_answer "diag.mode.burnin.$_slot.name" verify "$name_list"`
          else
            MyName=`getScriptSelection $_answer -noconfig "$name_list"`
          fi
	  /bin/echo script selection: $MyName
	fi
    else
      _answer=-1
    fi
  done
fi
# Convert old script name to process step name
MyName=`/bin/echo $MyName | /bin/sed -e "s/switch//g" -e "s/\.sh//g" -e "s/\.//g"`
MyName=`/bin/basename $MyName`
# find which field contains our defaults
name_found=0
# start default field off with an offset that compensates for the "N SCRIPTNAME"
DefaultField=3
ModeField=$DefaultField
for word in $name_list
do
  if [ "$word" = $MyName ]
  then
    name_found=1
  else
    if [ $name_found = 0 ]
    then
      DefaultField=`expr $DefaultField + 1`
    fi
    ModeField=`expr $ModeField + 1`
  fi
done
ModeField=`expr $ModeField + 1`
MinField=`expr $ModeField + 1`
MaxField=`expr $MinField + 1`
CommentField=`expr $MaxField + 1`
export ModeField DefaultOffset MinField MaxField CommentField
process_diagsetcycle diagsetcycle $arg
exit 0
