#!/usr/bin/env sh
#set -x

clear 

# Covert all upper case character to lower case characters.
upperToLower() {
  lowercase=$(echo $1 | awk 'BEGIN { getline; print $1=tolower($1) }')
}

#_LOGFILE=/var/cpq/Component.log
_STORUTIL_NEW=storcli-7.22.7.0
_STORUTIL_OLD=storcli-7.16.16.0
_HAWKSBILL=HPEMR416i-aGen10+

# Return codes

# Variables
silentFlag=1
ctrlID=-1
ctrlFWVer=""
psocFWVer=""
psocHWVer=""
latestPsocFwVer_type1=0x1e
latestPsocFwVer_type2=0x1e-0
Psoc5HwVer=0x7
defaultCtlrFwVer="52.22.3-4650"
firmware_binary=""
_COMP_LOGFILE=""

getOSPlateform(){
  echo ""
  OS=$(uname -o)
  OSVER=$(uname -r)
  output_CmpLog "OS version: $OS $OSVER"
}

getCmpXML() {
  directory_listing "." "[cC][Pp]0*.xml"
}

# Write information to stdout and the log file.
output_CmpLog() {
  if [ ! -d /var/cpq ]; then
	mkdir /var/cpq
  fi
	echo $1
	if [ 1 -eq $silentFlag ]; then
	 echo "[$(date '+%a %d %H:%M:%S')] $1" >> $_COMP_LOGFILE
  	else
	  echo "[$(date '+%a %d %H:%M:%S')] $1" | tee -a  $_COMP_LOGFILE
  	fi
}

file=""
# Search the specified directory (i.e. $1) for a specific file or file type (i.e. $2).
directory_listing() {
  #file=$(find "$1" -type f -iname "$2" | sed -e 's/^\.\///' 2> /dev/null)
  file=$(ls $2)
  _VER=`grep \<version $file | awk -F = '{print $2}' | awk '{gsub(/"/, "", $1); print $1}' | head -n 1`
  _COMP=`grep \<filename\> $file|awk -F '>' '{print $2}'|awk -F '<' '{print $1}'| awk '{gsub(/"/, "", $1); print $1}'`
  _DESCRIPT=`grep \<alt_name_xlate\ lang\=\"en\" $file|awk -F '>' '{print $2}'|awk -F '<' '{print $1}'|sed -e 's/\"//g'|tail -n 1`
  _FILENAME="${_COMP%.*}"
  _date=$(date '+%Y_%m_%d_%H_%M_%S')
  _package=$(echo $_COMP | cut -d'.' -f 1)
  _COMP_LOGFILE="/var/cpq/${_package}_${_date}.log"
 
  output_CmpLog "Component Log File : $_COMP_LOGFILE" 
  #output_CmpLog "Run with $NARGS Command Arguments(s): $ARGUS"
  output_CmpLog ""
  output_CmpLog "$_COMP - $_DESCRIPT"
  output_CmpLog "    Component Version: $_VER"
}

locateStorCLIUtil(){
  #storutil="$PWD/$_STORUTIL_NEW"
  storutil=$1
  if [ -e "$storutil" ]; then
    if [ ! -x "$storutil" ]; then
      chmod ug+x ${storutil}
    fi
    if [ ! -x "$storutil" ]; then
      output_CmpLog "Error: Cannot change the execute permission of $_STORUTIL_NEW"
      output_CmpLog "Script Exiting.."
      output_CmpLog "Exit Status: $INSTALL_NOT_ATTEMPTED"
      exit $INSTALL_NOT_ATTEMPTED
    else
      output_CmpLog "$storutil file check success"
    fi
  else
    output_CmpLog "Error: Cannot find StorCLI Utility"
    exit $INSTALL_NOT_ATTEMPTED
  fi
}


# This function Check to see if the file is readable.
isFileReadable() {
  #echo "isFileReadable"
  #output_CmpLog "readable file is $1"
  if [ ! -r $1 ]; then
    output_CmpLog "Error: $1 file is not readable, please make the file readable and re-run the script."
    output_CmpLog "Script exiting."
    output_CmpLog "Exit Status: $INSTALL_NOT_ATTEMPTED"
    exit $INSTALL_NOT_ATTEMPTED
  fi
}

parseXML() {
  xml_file=$file
  isFileReadable $PWD/$xml_file
  # Extract the name of the firmware binary file from the XML file.
  firmware_binary=$(grep -o -E "<FileName>(.*)</FileName>" "$PWD/$xml_file" | sed 's/FileName//g' | sed 's/<//g' | sed 's/>//g' | sed 's/\///g' | head -1)
  output_CmpLog "Firmware binary file name : $firmware_binary"
  if [ -z $firmware_binary ]; then
    output_CmpLog "No firmware binary file was found"
    output_CmpLog "Exit Status: $INSTALL_NOT_ATTEMPTED"
    exit $INSTALL_NOT_ATTEMPTED
  fi
  #isFileReadable $PWD/$firmware_binary
  # Read from the smart component's xml file and obtain the firmware version.
  #xml_file_firmware_version=$(grep 'version value=' "$xml_file" | head -1 | awk '{print $2}' | sed -e 's/value="\(.*\)"/\1/')
}

getBootCtrlInfo() {
	./$_STORUTIL_OLD show | grep -q HPEMR416i-aGen10+
	if [ $? -eq 0 ]; then
		output_CmpLog "HPEMR416i-aGen10+ controller found"
		ctrlID=$(./$_STORUTIL_OLD show | grep HPEMR416i-aGen10+ | awk '{print $1}')
		output_CmpLog "Conroller ID = $ctrlID"
	else
		output_CmpLog "Supported Controller HPEMR416i-aGen10+ not found"
		output_CmpLog "Exiting Smart Component"
		exit 2
	fi
}

getCntlrFWVer() {
	ctrlFWVer=$(./$_STORUTIL_OLD /c$ctrlID show all | grep "Firmware Package Build" | awk -F '= ' '{print $2}')
	output_CmpLog "Controller Firmware Version : $ctrlFWVer"
}

getPSOCFWVer() {
	psocFWVer=$(./$_STORUTIL_OLD /c$ctrlID show termlog type=contents | grep "PSoC FW Version" | awk '{print $NF}' | tail -n1 | sed 's/\r$//')
#	psocFWVer="0x1e 0xffff"
	output_CmpLog "PSOC Firmware version :  $psocFWVer"
}

getPSOCHWVer() {
	psocHWVer=$(./$_STORUTIL_OLD /c$ctrlID show termlog type=contents | grep "PSoC HW Version" | awk '{print $NF}' | tail -n1 | sed 's/\r$//')
	output_CmpLog "PSOC Hardware version :  $psocHWVer"
}

comparePSOCFWVer() {
	#when psoc fw version is 0xffff (corrupt value) by default proceding to fw flash
	#if [ $psocFWVer = "0xffff" ]; then
	if [ "$psocFWVer" = "0xffff" ] || [ "$psocFWVer" = "" ]; then
		output_CmpLog "Invalid part number found, PSOC FW version is corrupted, firmware flash may fail"
		output_CmpLog "Continuing with PSOC firmware flash process.."
		return
	fi

	#t1=$(printf "%d" "$psocFWVer")
	#t2=$(printf "%d" "$latestPsocFwVer")
	#if [ $t1 -lt $t2 ]; then
	if [ $psocHWVer == $Psoc5HwVer ] && [ $psocFWVer != $latestPsocFwVer_type1 ] && [ $psocFWVer != $latestPsocFwVer_type2 ]; then
		output_CmpLog "A newer version of PSOC firmware found"
		read -p "Do you want to continue with PSOC firmware flashing - (Y/N): " confirm
		#if [[ "$confirm" == [yY] || "$confirm" == [yY][eE][sS] ]]; then
		if [ "$confirm" == 'y' ] || [ "$confirm" == 'Y' ]; then
			output_CmpLog "Continue with flaishing new firmware.."
		else
			output_CmpLog "Exiting Smart Component"
			exit 5
		fi
	else
		output_CmpLog "PSOC Firmware is already upto date"
		output_CmpLog "Exiting Smart Component"
		exit 3
	fi
}

doFlash() {
	t1=$(echo $defaultCtlrFwVer | sed 's/[\.\-]//g')
	t2=$(echo $ctrlFWVer | sed 's/[\.\-]//g')
	echo ""
	if [ $t2 -lt $t1 ]; then
		output_CmpLog "Firmware flash in progress.."
		output=$(./$_STORUTIL_OLD /c$ctrlID download file=./$firmware_binary) 
		echo $output | grep "Status = Failure"
	else
		output_CmpLog "Firmware flash in progress.."
		output=$(./$_STORUTIL_NEW /c$ctrlID download file=./$firmware_binary)
		echo $output |  grep "Status = Failure"
	fi

	if [ $? -eq 0 ]; then
		echo ""
		output_CmpLog "Firmware update failed, Exiting Smart Component"
		exit 4
	else
		echo ""
		output_CmpLog "firmware update success. AC power cycle required"
		output_CmpLog "Please AC power cycle the system manually for the changes to take effect"
		output_CmpLog "Exiting Smart Component"
	fi
}

main(){
	getCmpXML
	parseXML
        output_CmpLog "Starting PSOC Firmware flashing Process"
	output_CmpLog "This may take up to 2 minutes"
        getOSPlateform
        locateStorCLIUtil $_STORUTIL_NEW
        locateStorCLIUtil $_STORUTIL_OLD
        getBootCtrlInfo
	getCntlrFWVer
	getPSOCFWVer
	getPSOCHWVer
	comparePSOCFWVer
	doFlash
}

main


# vim:ts=4:sw=4:et:
