#!/bin/sh

# INSTRUCTIONS: This patch is intended to be used prior to compiling ecCodes. It
# reduces the severity error/warning  when ecCodes encodes a missing data value
# to a BUFR file, otherwise an overwhelming number of warnings are output.
# Within the ropp2bufr_eccodes and eum2bufr_eccodes tools,
# ECCODES_BUFR_SET_TO_MISSING_IF_OUT_OF_RANGE is set to 1 to make sure
# that a missing data value is set in out-of-range cases.  If the ecCodes BUFR
# library is to be used to write missing data to BUFR files by other means than
# these tools, then this environment variable must be set to 1 manually.
#
# Users should provide the location of their unzipped ecCodes source,
# 'eccodes_path', as the (sole) command line argument.  If this is not set,
# the default location in $ROPP_SRC will be used instead.

# Location of un-tar'd eccodes source
eccodes_path=${1:-$ROPP_SRC/eccodes-2.12.5-Source/}
echo 'Using ecCodes path: '$eccodes_path
# Quit if can't find eccodes_path
if [[ ! -d "$eccodes_path" ]] ; then echo "ecCodes path '$eccodes_path' doesn't exist, please fix." ; exit ; fi

# Location of file to be edited
eccodes_file=$eccodes_path/src/grib_accessor_class_bufr_data_array.c
# Check the file is there:
if [ ! -f $eccodes_file ]; then
    echo "File not found, exiting. Make sure eccodes_path is set to top-level of unpacked ecCodes."
    exit 1
fi

# Check if version 2.16 or newer
cd $eccodes_path
package=eccodes-2
for d in $(ls -d $eccodes_path/../$package*); do
  thisdir=${d%%/}               # save this directory/name
  d=$(basename $d); d=${d#$1}   # remove <path><pack> parts
  v=$(expr index $d - 2>/dev/null)      # remove anything else before first '-'...
  if [[ v -le 0 ]]; then
    v=$(expr index $d _ 2>/dev/null)    # ... or '_' if no '-'
  fi
  if [[ v -gt 0 ]]; then
    thisver=${d:$v}                     # what's left is <vers>
  else
    thisver="0"  # assume files with no detectable version are 'v0'
  fi
  if [[ -z "$latestver" ]]; then        # initialise with first file found
    latestdir=$thisdir
    latestver=$thisver
  fi
  if [[ $thisver > $latestver ]]; then  # update if higher <vers>
    latestdir=$thisdir
    latestver=$thisver
  fi
done

if [[ $latestver > 2.16 ]] ; then
  version_2_16_onwards=true
else
  version_2_16_onwards=false
fi


# If grep doesn't find 3 instances of the pattern, code may have changed, so don't proceed with the patch
n_instances=$(grep -n "Setting it to missing value" $eccodes_file | wc -l)
if [ $n_instances != 3 ] ; then echo "Wrong number of instances found. Exiting" && exit 2 ; fi

# Get line numbers where we need to edit
first=$(grep -n "Setting it to missing value" $eccodes_file | cut -f1 -d: | head -1 )
second=$(grep -n "Setting it to missing value" $eccodes_file | cut -f1 -d: | head -2 | tail -1)
third=$(grep -n "Setting it to missing value" $eccodes_file | cut -f1 -d: | tail -1 )

first="$(($first-1))"
second="$(($second-1))"
third="$(($third-1))"

# Make a backup of the file we're about to edit, if the backup doesn't already exist
if [[ ! -f ${eccodes_file}_backup ]] ; then
  cp $eccodes_file ${eccodes_file}_backup
fi

# Check that backup was made
if [[ ! -f ${eccodes_file}_backup ]] ; then
  echo "Backup was not created. Check permissions? Exiting."
  exit
fi

# Change the error type to GRIB_LOG_DEBUG
if [ "$version_2_16_onwards" = false ] ; then
  sed -i "$first"','"$first"'s/GRIB_LOG_ERROR/GRIB_LOG_DEBUG/' $eccodes_file
  sed -i "$second"','"$second"'s/GRIB_LOG_ERROR/GRIB_LOG_DEBUG/' $eccodes_file
  sed -i "$third"','"$third"'s/GRIB_LOG_ERROR/GRIB_LOG_DEBUG/' $eccodes_file
fi

if [ "$version_2_16_onwards" = true ] ; then
  sed -i "$first"','"$first"'s/ECCODES WARNING/GRIB_LOG_DEBUG/' $eccodes_file
  sed -i "$second"','"$second"'s/ECCODES WARNING/GRIB_LOG_DEBUG/' $eccodes_file
  sed -i "$third"','"$third"'s/ECCODES WARNING/GRIB_LOG_DEBUG/' $eccodes_file
fi

#grep for GRIB_LOG_DEBUG on the relevant lines to test success
if sed "$first"'q;d' $eccodes_file | grep -q GRIB_LOG_DEBUG $eccodes_file ; then

  if sed "$second"'q;d' $eccodes_file | grep -q GRIB_LOG_DEBUG $eccodes_file ; then

    if sed "$third"'q;d' $eccodes_file | grep -q GRIB_LOG_DEBUG $eccodes_file ; then

      printf '\nSuccess. Look at the difference between grib_accessor_class_bufr_data_array.c
              and grib_accessor_class_bufr_data_array.c_backup to make sure
              the patch has been applied correctly.\n\n'

    fi

  fi

else

   printf '\nThere was a problem applying the patch. Try double checking that eccodes exists
           and is unpacked at the path you supplied for $eccodes_path in this script.\n\n'

fi
