#!/bin/ksh
#
# An example script for building AAPP v8 and OPS-LRS v8 with various external
# libraries.
#
# Creates the following subdirectories:
#
#     tarfiles
#     install
#           bufrdc
#           eccodes
#           hdf5
#           AAPP_8.15
#           opslrs
#           kai
#     build
#           bufrdc_000409
#           eccodes-2.38.0-Source
#           eccodes_build
#           hdf5-1.10.6
#           AAPP_8.15
#           OPS_V8.4-AAPP-l-20211216
#           xerces-c-src1_7_0
#           fftw-3.0.1
#           gettext-0.19.8.1 [if autopoint is not already installed]
#           flex-flex-2.5.39 [if libfl.a is not already installed]
#           kai-1.12
#
# Assumes that the external libraries are not centrally installed, and that the
# user does not have root privilege. You can modify the script if you want to
# use centrally-installed libraries.
#
# You should check the settings at the top of the script and change them to
# suit your system (e.g. station name).
#
# The AAPP and OPS-LRS tar files need to be manually downloaded from the NWPSAF
# web site, with the user logged into the site, and placed in the "tarfiles"
# directory. The other files are downloaded automatically if they are not 
# already present in "tarfiles". It is recommended to use the latest version of
# the ecCodes library.
#
# 01/11/2017 NCA
# 22/01/2017 Update
# 31/01/2017 Add -lhdf5_hl -lhdf5_fortran in the AAPP configure step
# 23/02/2018 Update for OPS-LRS v8.0
# 27/09/2018 AAPP v8.2; ecCodes v2.8.2; update url for aapp_data_files
# 20/12/2018 AAPP v8.3; ecCodes v2.10.0
# 18/04/2019 AAPP v8.4; eccodes v2.12.0. Include autopoint (from gettext),
#            which is a prerequisite for building flex
# 05/12/2019 Add comment in bufrdc build; use eccodes v2.15.0.
# 09/12/2019 AAPP v8.5; check cmake version is sufficient for ecCodes
# 06/02/2020 Correction to cmake version checking
# 12/08/2020 AAPP v8.6; flex 2.5.39 (as 2.5.35 is no longer available); eccodes v2.18.0
# 03/09/2020 Port to nwp-saf.eumetsat.int
# 04/02/2021 AAPP v8.7
# 02/08/2021 AAPP v8.8, ecCodes 2.22.1
# 16/09/2021 Add --no-check-certificate in calls to wget for BUFRDC and ecCodes (BoM suggestion)
# 22/09/2021 Modify OPS-LRS "configure" script for compatibility with perl 5.26 and later. Add some error traps.
# 15/12/2021 Update url for BUFRDC and ecCodes; use ecCodes 2.24.0
# 07/02/2022 Add kai option. AAPP v8.9; OPS_V8.4-AAPP-l-20211216; ecCodes 2.24.2
# 30/06/2022 AAPP v8.10; ecCodes 2.26.0
# 12/10/2022 Test whether aec is installed (turned on by default in ecCodes >=2.25.0)
# 05/01/2023 AAPP v8.11; ecCodes 2.27.1
# 07/08/2023 AAPP v8.12. By default we have left ecCodes at 2.27.1, but the user may wish to
#            update to 2.31.0 provided they have a suitable C++ compiler; this script checks
#            compatibility.
# 04/06/2024 AAPP v8.13. Download kai from new EUMETSAT User Portal.
# 02/09/2024 Improve script ease of use and maintainability.
#            Update bug work-arounds for OPS-LRS.
# 18/06/2024 AAPP v8.13 release.
# 30/09/2024 Update ecCodes 2.38.0 (supporting BUFR tables v40); hdf5 1.10.6
#            Add netCDF (steps 12 and 13) and AAPP-AWS (step 14)
#            Set flags for compatibility with gcc/11
# 18/11/2024 Get it working on intel/2021 compiler at ECMWF
# 20/01/2025 AAPP v8.14 release.
# 30/06/2025 AAPP v8.15 release.
#########################################################################

echo "Running: ${0}  ($(date))"

usage(){
  echo "\
  Usage: ./install_aapp8 item
  where item is:
    1 for HDF5 (with Fortran interfaces)
    2 for BUFRDC
    3 for ecCodes
    4 for AAPP
    5 for AAPP MAIA4 data files
    6 for fftw (needed for OPS-LRS)
    7 for xerces (needed for OPS-LRS)
    8 for flex and autopoint (checks whether they are centrally installed)
    9 for OPS-LRS
   10 for current set of OPS-LRS auxiliary files
   11 for kai
   12 for netCDF-C (needed for Arctic Weather Satellite)
   13 for netCDF-F (needed for Arctic Weather Satellite)
   14 for AAPP-AWS

  "
}

item=$1
[ $item ] || { usage; exit 1; }


#### CONSTANTS

AAPP_VERSION=8.15           #to correspond with the name of the AAPP tar file
FORTRAN_COMPILER=${FORTRAN_COMPILER:-gfortran}   #gfortran, ifort (or pgf90 if you are not building OPS-LRS)
STATION=${STATION:-"exeter"}    #change as required
SITE_ID=${SITE_ID:-"UKM"}       #change as required
NTHREADS=${NTHREADS:-8}  #for OPS-LRS. Depends on the number of cores you have available,
                         #but aim for a multiple of 4 if possible. It can be changed later,
                         #by editing OPS-LRS-run/OPS/conf/OPS_SD.cfg

export FC=${FORTRAN_COMPILER}
export CC=${CC:-gcc}
export CXX=${CXX:-g++}

# Package versions
HDF5_VERSION="hdf5-1.10.6"
BUFRDC_VERSION="bufrdc_000409"
ECCODES_VERSION="2.38.0"    # AWS need 2.31
FFTW_VERSION="fftw-3.0.1"
XERCES_VERSION="xerces-c-1.7.0"
FLEX_VERSION="flex-2.5.39"
GETTEXT_VERSION="gettext-0.19.8.1"
OPS_LRS_VERSION="OPS_V8.4-AAPP-l-20211216"
# use zip files as names include the hash
KAI_ZIP="kai_1_12_e8b74685d1.zip"
NETCDF_C_VERSION="4.8.1"
NETCDF_F_VERSION="4.5.3"

# Directories
CWD_ORIG=${PWD}

# The directory where the dependent packages should be installed
TOP=${TOP:-${CWD_ORIG}}
TOP=$(readlink -f ${TOP})

TAR=${TOP}/tarfiles
BUILD=${TOP}/build
INSTALL=${TOP}/install

HDF5_INSTALL_DIR=${INSTALL}/hdf5
BUFRDC_INSTALL_DIR=${INSTALL}/bufrdc
ECCODES_INSTALL_DIR=${INSTALL}/eccodes
AAPP_INSTALL_DIR=${INSTALL}/AAPP_${AAPP_VERSION}
AAPP_INSTALL_MAIA4_DATA_DIR=${AAPP_INSTALL_DIR}/AAPP/data_maia4
OPSLRS_EXT_INSTALL_DIR=${INSTALL}/opslrs
FFTW_INSTALL_DIR=${OPSLRS_EXT_INSTALL_DIR}/${FFTW_VERSION}
XERCES_INSTALL_DIR=${OPSLRS_EXT_INSTALL_DIR}/${XERCES_VERSION}
FLEX_INSTALL_DIR=${OPSLRS_EXT_INSTALL_DIR}/flex-${FLEX_VERSION}
OPSLRS_INSTALL_DIR=${INSTALL}/opslrs
KAI_INSTALL_DIR=${INSTALL}/kai
NETCDF_INSTALL_DIR=${INSTALL}/hdf5  # for netCDF-C and netCDF-Fortran,
                                    # installed into same location as hdf5 library
                                    # since netCDF depends on hdf5
NETCDF_C_SYMLINK=${INSTALL}/netcdf-c
NETCDF_F_SYMLINK=${INSTALL}/netcdf-f
AAPP_AWS_INSTALL_DIR=${AAPP_INSTALL_DIR}/AAPP-AWS

#### MAIN

echo -e "\
Installing dependencies at directory: TOP=${TOP}
Installing item: ${item}

AAPP_VERSION: ${AAPP_VERSION}
FORTRAN_COMPILER: ${FORTRAN_COMPILER}
STATION: ${STATION}
SITE_ID: ${SITE_ID}
NTHREADS (for OPS): ${NTHREADS}
"

mkdir -p $TAR $BUILD $INSTALL

############# HDF5 version 1.10.6

if [ $item = 1 ]; then

  echo -e "\n** Installing HDF5  (version: ${HDF5_VERSION}) **"

  mkdir -p $HDF5_INSTALL_DIR

  cd $TAR
  tarfile=${HDF5_VERSION}.tar.gz
  # e.g. for version hdf5-1.10.6, https://support.hdfgroup.org/ftp/HDF5/releases/hdf5-1.10/hdf5-1.10.6/src/
  url="https://support.hdfgroup.org/ftp/HDF5/releases/${HDF5_VERSION%.*}/${HDF5_VERSION}/src/"
  [ -s $tarfile ] || { echo "Downloading HDF5"; wget ${url}${tarfile}; }
  [ -s $tarfile ] || { echo "Failed to download $tarfile"; exit 1; }

  cd $BUILD
  dir=${tarfile%.tar.gz}
  [ -d $dir ] || { echo "unpacking HDF5"; tar -xzf $TAR/$tarfile; }

  cd $dir
  mkdir -p $HDF5_INSTALL_DIR

  ./configure --prefix=$HDF5_INSTALL_DIR --enable-fortran \
    && echo "hdf5 configure: OK" || { echo "problem with hdf5 configure"; exit 1; }
  make || { echo "problem with hdf5 make"; exit 1; }
  make install || { echo "problem with hdf5 make install"; exit 1; }
  echo "Finished hdf5 build"

fi

############# BUFRDC version 409
# Note: you may have to check the download url is still valid, 
# see https://confluence.ecmwf.int/display/BUFR/BUFRDC+Home

if [ $item = 2 ]; then

  echo -e "\n** Installing BUFRDC  (version: ${BUFRDC_VERSION}) **"

  mkdir -p ${BUFRDC_INSTALL_DIR}

  cd $TAR
  tarfile=${BUFRDC_VERSION}.tar.gz
  url="https://confluence.ecmwf.int/download/attachments/35752466/"
  [ -s $tarfile ] || { echo "Downloading BUFRDC"; wget --no-check-certificate ${url}${tarfile}; }
  [ -s $tarfile ] || { echo "Failed to download $tarfile"; exit 1; }

#BUFRDC build can fail in buevar.F if the install directory has 47 characters
#or more, so create a link in /tmp

  BUFRDC_INSTALL_DIR_ORIG=""
  if [ ${#BUFRDC_INSTALL_DIR} -ge 47 ]; then
    echo "Too many characters in $BUFRDC_INSTALL_DIR"
    BUFRDC_INSTALL_DIR_ORIG=$BUFRDC_INSTALL_DIR
    BUFRDC_INSTALL_DIR=/tmp/bufrdc_install
    echo "Creating a link:  ${BUFRDC_INSTALL_DIR}"
    rm -f $BUFRDC_INSTALL_DIR
    ln -sf $BUFRDC_INSTALL_DIR_ORIG $BUFRDC_INSTALL_DIR || { echo "unable to create $BUFRDC_INSTALL_DIR"; exit 1; }
  fi

  cd $BUILD
  dir=${tarfile%.tar.gz}
  [ -d $dir ] || { echo "unpacking BUFRDC"; tar -xzf $TAR/$tarfile; }
  [ -d $dir ] || { echo "problem unpacking BUFRDC"; exit 1; }
  cd $dir
  
  if [[ $FORTRAN_COMPILER == gfortran ]]; then
    echo "Adding -std=legacy to FFLAGS"
    chmod 755 config/config.linux_gfortranA64.in
    sed -i 's#FFLAGS = $(DEBUG)#FFLAGS = -std=legacy $(DEBUG)#' config/config.linux_gfortranA64.in
  fi

  echo "Building BUFRDC ..."

  case $FORTRAN_COMPILER in
    gfortran) reply=y;;
    pgf90)    reply=n;;
    ifort)    reply=i;;
    *) echo "unsupported compiler"
       exit 1;;
  esac

  # Wrap BUFRC building in set +e as it will throw errors that can be ignored.
  check_set_minus_e=$([[ $- == *e* ]] && echo 'true' || echo 'false') 
  set +e
  ./build_library <<EOF
$reply
n
$BUFRDC_INSTALL_DIR
EOF
  ./install
  [[ "${check_set_minus_e}" == 'true' ]] && set -e || set +e

  [ $BUFRDC_INSTALL_DIR_ORIG ] && BUFRDC_INSTALL_DIR=BUFRDC_INSTALL_DIR_ORIG
  echo "Finished BUFRDC build"
  echo 'If you saw an error in the step "./test.sh", this can be ignored as it is not critical for AAPP' 

fi

############# ecCodes
# Note: you may have to check the download url is still valid, 
# see https://confluence.ecmwf.int/display/ECC/Releases
# In general, you should use the latest available release of ecCodes.

if [ $item = 3 ]; then

  echo -e "\n** Installing ecCodes  (version: ${ECCODES_VERSION}) **"

  mkdir -p ${ECCODES_INSTALL_DIR}

  set $(IFS=.; echo ${ECCODES_VERSION})
  ec1=$1
  ec2=$2

  if [ $CXX = g++ ]; then

  echo "Checking g++ requirements for ecCodes v${ECCODES_VERSION}..."

#ecCodes 2.29.0 requires C++11 (g++ v4.8.1)
#ecCodes 2.31.0 requires C++17 (g++ v8)

  if [[ $ec1 -gt 2 || $ec1 -eq 2 && $ec2 -ge 29 ]]; then
    set $(g++ --version) || { echo "Error: g++ is needed for ecCodes from v2.29 but cannot be run"; exit 1; }
    gppversion=$3
    if [[ $ec1 -gt 2 || $ec1 -eq 2 && $ec2 -ge 31 ]]; then
      set $(IFS=.; echo $gppversion)
      gpp1=$1
      if [[ $gpp1 -lt 8 ]]; then
        echo "Error: g++ v8 or higher (supporting C++17) is needed for ecCodes from v2.31, found $gppversion"
        exit 1
      fi
      echo "... g++ v$gppversion is OK"
    else
      echo "... g++ v$gppversion is OK"
    fi
  else
    echo "... not required"
  fi

  fi    #end of g++ check

  echo "Checking cmake requirements for ecCodes v${ECCODES_VERSION}..."

#ecCodes 2.13.0 requires cmake 3.6
#ecCodes 2.19.0 requires cmake 3.12

  set $(cmake --version) || { echo "Error: cannot run cmake"; exit 1; }
  cmakev=${3}
  set $(IFS=.; echo $cmakev)
  cmake1=$1
  cmake2=$2

  if [[ $ec1 -eq 2 && $ec2 -ge 13 && $ec2 -lt 19 ]]; then
    if [[ $cmake1 -lt 3 || $cmake1 -eq 3 && $cmake2 -lt 6 ]]; then
      echo "Error: cmake version $cmakev is <3.6.0; you will not be able to build eccodes v2.13.0 or later"
      echo "Recommend to install a recent cmake (v3.6.0 or higher), or modify this script to set ECCODES_VERSION=2.12.5"
      exit 1
    else
      echo "... cmake v$cmakev is OK"
    fi
  elif [[ $ec1 -gt 2 || $ec1 -eq 2 && $ec2 -ge 19 ]]; then
    if [[ $cmake1 -lt 3 || $cmake1 -eq 3 && $cmake2 -lt 12 ]]; then
      echo "Error: cmake version $cmakev is <3.12.0; you will not be able to build eccodes v2.19.0 or later"
      echo "Recommend to install a recent cmake (v3.12.0 or higher), or modify this script to set ECCODES_VERSION=2.18.0"
      exit 1
    else
      echo "... cmake v$cmakev is OK"
    fi
  fi  

  cd $TAR
  tarfile=eccodes-${ECCODES_VERSION}-Source.tar.gz
  url="https://confluence.ecmwf.int/download/attachments/45757960/"
  [ -s $tarfile ] || { echo "Downloading ecCodes"; wget --no-check-certificate ${url}${tarfile}; }
  [ -s $tarfile ] || { echo "Failed to download $tarfile"; exit 1; }

  cd $BUILD
  dir=${tarfile%.tar.gz}
  [ -d $dir ] || { echo "unpacking ecCodes"; tar -xzf $TAR/$tarfile; }

  echo "Building ecCodes ..."

  mkdir -p eccodes_build
  cd eccodes_build
  [ $(aec 2>/dev/null; echo $?) -le 1 ] || aecflag="-DENABLE_AEC=OFF"   #test whether Adaptive Entropy Encoding is available

  cmake \
    -DCMAKE_INSTALL_PREFIX=${ECCODES_INSTALL_DIR} \
    -DCMAKE_Fortran_COMPILER=${FORTRAN_COMPILER} $aecflag \
    $BUILD/$dir
  make || { echo "problem with ecCodes make"; exit 1; }
  make install >install.out || { echo "problem with ecCodes make install"; exit 1; }
  echo "Finished ecCodes build"

fi

############# AAPP
# Note: if some or all of the external libraries are centrally installed then you should modify the configure
# step (remove -L...) and no need to modify LD_LIBRARY_PATH.

if [ $item = 4 ]; then

  echo -e "\n** Installing AAPP (version: ${AAPP_VERSION}) **"

  mkdir -p ${AAPP_INSTALL_DIR}

  cd $TAR
  tarfile=AAPP_${AAPP_VERSION}.tgz

  if [ ! -s $tarfile ]; then
    echo "Please put $tarfile in directory $TAR"
    exit 1
  fi

  cd $BUILD
  dir=${tarfile%.tgz}
  [ -d $dir ] || { echo "unpacking AAPP"; tar -xzf $TAR/$tarfile; }

  cd $dir
  set -x
  [ -d $ECCODES_INSTALL_DIR/lib ] && ECCODES_LIB=$ECCODES_INSTALL_DIR/lib \
                                  || ECCODES_LIB=$ECCODES_INSTALL_DIR/lib64
  ./configure \
    --station=$STATION \
    --fortran-compiler=$FORTRAN_COMPILER \
    --site-id=$SITE_ID \
    --external-libs="-L$BUFRDC_INSTALL_DIR -lbufr -L${ECCODES_LIB} -leccodes_f90 -leccodes -L$HDF5_INSTALL_DIR/lib -lhdf5 -lhdf5_hl -lhdf5_fortran -lhdf5hl_fortran" \
    --external-includes="-I$HDF5_INSTALL_DIR/include -I$ECCODES_INSTALL_DIR/include" \
    --prefix=$AAPP_INSTALL_DIR
  status=$?
  set +x
  [[ ${status} -eq 0 ]] && echo "AAPP configure: OK" || { echo "Error: AAPP configure failed" ; exit 1 ; }

#set up LD_LIBRARY_PATH in ATOVS_ENV8
  sed -i s#DIR_HDF5=#DIR_HDF5=$HDF5_INSTALL_DIR# ATOVS_ENV8
  sed -i s#DIR_ECCODES=#DIR_ECCODES=$ECCODES_INSTALL_DIR# ATOVS_ENV8

  echo "Building AAPP ..."
  echo "See logs files: ${PWD}/make.out , ${PWD}/make.err "
  make >make.out 2>make.err || { echo "AAPP make failed"; exit 1; }
  make install || { echo "AAPP make install failed"; exit 1; }
  echo "AAPP make install:  OK"

#Make sure the installed AVHRR vis cal files have the original date, not the installation date.
#(They will get updated from the internet when you run avh_get_vis_coefs).
  cp -p AAPP/src/calibration/libavhrcl/*.txt $AAPP_INSTALL_DIR/AAPP/data/calibration/coef/avhcl

  echo "Finished AAPP build"

fi


############# AAPP MAIA4 data

if [ $item = 5 ]; then

  echo -e "\n** Installing AAPP MAIA4 **"

  cd $TAR
  url=https://nwp-saf.eumetsat.int/downloads/aapp_data_files/maia_data_files/

  tarfile=AAPP_MAIA4_thresholds_v8.tgz
  [ -s $tarfile ] || { echo "Downloading $tarfile"; wget ${url}${tarfile}; }
  [ -s $tarfile ] || { echo "Problem downloading $tarfile"; exit 1; }
  tarfile=AAPP_MAIA4_atlas.tgz
  [ -s $tarfile ] || { echo "Downloading $tarfile"; wget ${url}${tarfile}; }
  [ -s $tarfile ] || { echo "Problem downloading $tarfile"; exit 1; }
  tarfile=AAPP_MAIA4_atlas_extra.tgz
  [ -s $tarfile ] || { echo "Downloading $tarfile"; wget ${url}${tarfile}; }
  [ -s $tarfile ] || { echo "Problem downloading $tarfile"; exit 1; }
  cd $BUILD
  [ -d AAPP/data_maia4/thresholds ] || { echo "Unpacking thresholds"; tar -xzf ${TAR}/AAPP_MAIA4_thresholds_v8.tgz; }
  [ -d AAPP/data_maia4/atlas ] || { echo "Unpacking atlas"; tar -xzf ${TAR}/AAPP_MAIA4_atlas.tgz; }
  [ -f AAPP/data_maia4/atlas/ecmwf_grib_surface.grb ] || { echo "Unpacking atlas_extra"; tar -xzf ${TAR}/AAPP_MAIA4_atlas_extra.tgz; }
  [[ -L data_maia4 ]] || ln -s AAPP/data_maia4

  # Add data_maia4 files into AAPP, if not already present
  if [[ ! -d ${AAPP_INSTALL_MAIA4_DATA_DIR} ]] || [[ ! -L ${AAPP_INSTALL_MAIA4_DATA_DIR} ]]; then
    cd $(dirname ${AAPP_INSTALL_MAIA4_DATA_DIR})
    ln -sf $(realpath --relative-to=${PWD} ${BUILD}/data_maia4) data_maia4
  fi
fi

############# fftw
 
if [ $item = 6 ]; then

  echo -e "\n** Installing fftw  (version: ${FFTW_VERSION}) **"

  mkdir -p $(dirname ${FFTW_INSTALL_DIR})

  cd $TAR
  url=https://nwp-saf.eumetsat.int/downloads/aapp_data_files/OPS-LRS/external_libs/

  tarfile=${FFTW_VERSION}.tar.gz
  [ -s $tarfile ] || { echo "Downloading ${tarfile}"; wget ${url}${tarfile}; }
  [ -s $tarfile ] || { echo "Failed to download ${tarfile}"; exit 1; }

  cd $BUILD
  dir=${tarfile%.tar.gz}
  [ -d $dir ] || { echo "unpacking fftw"; tar -xzf ${TAR}/${tarfile}; }

  cd $dir
  ./configure --prefix=${FFTW_INSTALL_DIR} \
    && echo "fftw configure: OK" || { echo "ERROR: problem with fftw configure" ; exit 1 ; }
  make || { echo "make failed for ${FFTW_VERSION}"; exit 1; }
  make install || { echo "make install failed for ${FFTW_VERSION}"; exit 1; }
  echo "Finished ${FFTW_VERSION} build"

fi

############# xerces
 
if [ $item = 7 ]; then

  echo -e "\n** Installing xerces-c  (version: ${XERCES_VERSION}) **"

  mkdir -p $(dirname ${XERCES_INSTALL_DIR})

  # Construct tarfile name, e.g. xerces-c-src1_7_0.tar.gz for version xerces-c-1.7.0
  version_underscores=$(echo ${XERCES_VERSION##*-} | tr '.' '_')
  tarfile=xerces-c-src${version_underscores}.tar.gz
  
  cd $TAR
  url=https://nwp-saf.eumetsat.int/downloads/aapp_data_files/OPS-LRS/external_libs/

  file=iostream.h        #missing from modern Linux distributions
  [ -s $file ] || { echo "Downloading iostream.h"; wget ${url}${file}; }

  [ -s $tarfile ] || { echo "Downloading ${tarfile}"; wget ${url}${tarfile}; }
  [ -s $tarfile ] || { echo "Failed to download ${tarfile}"; exit 1; }

  cd $BUILD
  dir=${tarfile%.tar.gz}
  [ -d $dir ] || { echo "unpacking xerces"; tar -xzf $TAR/$tarfile; }
  
  #For modern Intel and GNU compilers we need to change XMLString.cpp due
  # to its use of non-standard functions stricmp and strnicmp
  file=xerces-c-src1_7_0/src/xercesc/util/XMLString.cpp
  a="$(grep strings.h $file)"
  if [ -z "$a" ]; then
    echo "Modifying $file as required to support modern compilers"
    sed -i "s/#include <string.h>/#include <string.h>\n#include <strings.h>/" $file
    sed -i s/stricmp/strcasecmp/ $file
    sed -i s/strnicmp/strncasecmp/ $file
  fi

  cp $TAR/iostream.h $dir/src/xercesc/util/NetAccessors/Socket
  cd $dir/src/xercesc/util/NetAccessors/Socket
  sed -i 's/#include <iostream.h>/#include "iostream.h"/' UnixHTTPURLInputStream.cpp
  
  export XERCESCROOT=$BUILD/$dir
  cd ${XERCESCROOT}/src/xercesc
  sh ./runConfigure -p linux -c $CC -x $CXX -r pthread -P ${XERCES_INSTALL_DIR} \
    && echo "xercesc configure: OK" || { echo "ERROR: problem with xercesc configure" ; exit 1 ; }
  make || { echo "make failed for ${XERCES_VERSION}"; exit 1; }
  make install || { echo "make install failed for ${XERCES_VERSION}"; exit 1; }
  echo "Finished ${XERCES_VERSION} build"

fi  


############# flex

if [ $item = 8 ]; then

  echo -e "\n** Installing flex  (version: ${FLEX_VERSION}) **"

  mkdir -p $(dirname ${FLEX_INSTALL_DIR})

  flex_found=$($CC -lfl >/dev/null 2>&1 && echo 'true' || echo 'false' )
  if [[ "${flex_found}" == "false" ]]; then
    echo "flex is not centrally installed"
    if [ -s ${FLEX_INSTALL_DIR}/lib/libfl.a ]; then
      echo "but found at ${FLEX_INSTALL_DIR}/lib/libfl.a"
      flex_found="true"
    fi
  fi

  if [[ "${flex_found}" == "false" ]]; then
  
#Flex install requires autopoint, which is part of gettext, see https://www.gnu.org/software/gettext/
#  http://ftp.gnu.org/pub/gnu/gettext/gettext-0.19.8.1.tar.gz

    autopoint_found=$(autopoint --version >/dev/null 2>&1 && echo 'true' || echo 'false' )
    if [[ "${autopoint_found}" == "false" ]]; then
      echo "autopoint is not in the default PATH"
      url=http://ftp.gnu.org/pub/gnu/gettext
      tarfile=${GETTEXT_VERSION}.tar.gz
      dir=${GETTEXT_VERSION}
      gettext_install_dir=${OPSLRS_EXT_INSTALL_DIR}/${dir}
      
      if [ ! -x ${gettext_install_dir}/bin/autopoint ]; then
        echo "autopoint is a pre-requisite for flex: installing gettext"
        cd $TAR
        [ -s $tarfile ] || { echo "Downloading gettext"; wget ${url}/${tarfile}; }
        cd $BUILD
        [ -d $dir ] || { echo "unpacking gettext"; tar -xzf $TAR/$tarfile; }
        [ -d $dir ] || { echo "$dir not found, please check the gettext tar file"; exit 1; }
        cd $dir
        echo "configuring gettext"
        ./configure --prefix=${gettext_install_dir} \
          && echo "gettext configure: OK" || { echo "ERROR: problem with gettext configure" ; exit 1 ; }
        echo "building gettext"
        make || { echo "make failed for $dir"; exit 1; }
        make install
      else
        echo "found autopoint at ${gettext_install_dir}/bin"
      fi
      echo "adding to PATH: ${gettext_install_dir}/bin"
      PATH=${gettext_install_dir}/bin:$PATH
      autopointv="$(autopoint --version)" || { echo "autopoint still not found; need to troubleshoot"; exit 1; }
    fi

#Flex releases are linked from https://github.com/westes/flex/releases, e.g.
#  https://github.com/westes/flex/releases/download/v2.6.4/flex-2.6.4.tar.gz
#  https://github.com/westes/flex/archive/flex-2.5.39.tar.gz
#  https://github.com/westes/flex/archive/v2.6.0.tar.gz
#For OPS-LRS it may be safest to use an old release. 

    cd $TAR
    url=https://github.com/westes/flex/archive
    tarfile=${FLEX_VERSION}.tar.gz

    [ -s $tarfile ] || { echo "Downloading flex (${tarfile}) "; wget ${url}/${tarfile} ; }

    cd $BUILD
    dir=$(basename ${FLEX_INSTALL_DIR})
    [ -d $dir ] || { echo "unpacking flex"; tar -xzf $TAR/$tarfile; }
    [ -d $dir ] || { echo "$dir not found, please check the flex tar file"; exit 1; }

    cd $dir
    echo "run autogen.sh in $PWD"
    ./autogen.sh
    echo "configure flex"
    ./configure --prefix=${FLEX_INSTALL_DIR} \
      && echo "flex configure: OK" || { echo "ERROR: problem with flex configure" ; exit 1 ; }
    echo "Building flex..."
    make || echo "make failed for $dir"    #continue if there are errors, and check libfl.a afterwards
    make install

    if [ -s ${FLEX_INSTALL_DIR}/lib/libfl.a ]; then
      echo "Finished flex build (you can ignore preceding error messages)"
      echo "libfl.a has been created successfully"
    else
      echo "Failed to create libfl.a"
      exit 1
    fi

  else
    echo "libfl.a is installed"
  fi
fi


############# OPS-LRS version 8 

if [ $item = 9 ]; then

  echo -e "\n** Installing OPS-LRS  (version: ${OPS_LRS_VERSION}) **"

  mkdir -p ${OPSLRS_INSTALL_DIR}

#This script unpacks the tar files currently on the NWPSAF server.

#Check the tar files

  cd $TAR
  tarfile=${OPS_LRS_VERSION}.tgz
  [ -s $tarfile ] || { echo "Please put $tarfile in directory $TAR"; exit 1; }

#Unpack the tar files
  echo "Unpacking $TAR/$tarfile"
  cd $BUILD
  tar -xzf $TAR/$tarfile
  cd ${OPS_LRS_VERSION}

# Workaround known bugs.
# (See AAPP bugs page: https://nwp-saf.eumetsat.int/site/software/aapp/updates/)
  # 1. Modify the configure script so that it works with perl 5.26 and later
  #    NOTE: No longer needed for version OPS_V8.4 or later (fixed in OPS_V8.4.)
  # echo "Modifying the OPS-LRS configure script"
  # cp -p configure configure_old
  # sed 's#do "config/$opts{arch}"#do "./config/$opts{arch}"#' configure_old >configure
  # diff configure configure_old
  #
  # 2. Modify the config/Linux-gfortran file to add the omitted "-Wl,--end-group"
  #    flag to close the -Wl group.
  file=config/Linux-gfortran
  str="          -lpthread -lnsl -lrt -lm -lc"
  sed -i "s/${str}/${str} -Wl,--end-group/g" ${file}

  # 3. Add "./" in OPS.pm
  file=run/OPS/perl/lib/IASI/OPS.pm
  str="do 'processiasi.pl'"
  str1="do './processiasi.pl'"
  sed -i "s!${str}!${str1}!" ${file}

#Copy libfl.a if it has been created by previous step
  libfl=${FLEX_INSTALL_DIR}/lib/libfl.a
  if [ -s $libfl ]; then
    echo "copying libfl.a"
    cp $libfl src/EXT/env/lib
  fi

#For gfortran, check whether libgfortranbegin.a is present. It is obsolete on modern systems.
#If not present, remove it from Linux-gfortran config file.

  if [ $FORTRAN_COMPILER = gfortran ]; then
    gfortranbegin_found=$(gcc -lgfortranbegin >/dev/null 2>&1 && echo 'true' || echo 'false' )
    if [[ "${gfortranbegin_found}" == "false" ]]; then
      echo "removing -lgfortranbegin from config/Linux-gfortran"
      sed -i 's/-lgfortranbegin//' config/Linux-gfortran
    fi
  fi

#Modify the config/Linux-gfortran so that it works with gcc11 and later

  if [ $FORTRAN_COMPILER = gfortran ]; then
    set $(g++ --version) || { echo "Error: g++ is needed for OPS-LRS but cannot be run"; exit 1; }
    version=${3%%.*}
    if [ $version -ge 11 ]; then
      echo "adding -std=c++11 in config/Linux-gfortran"
      sed -i "s#ARCH_CPPFLAGS_NORMAL => '-g -O3'#ARCH_CPPFLAGS_NORMAL => '-g -O3 -std=c++11'#" config/Linux-gfortran
    fi
  fi

#Configure and make OPS-LRS

  case $FORTRAN_COMPILER in
    gfortran) arch=Linux-gfortran;;
    ifort)    arch=Linux-Intel;;
    *) echo "unsupported compiler"    #note: pgf90 not supported for OPS-LRS
       exit 1;;
  esac
  if [ $arch = Linux-Intel ]; then    #if ifort is selected, use icc if available
    icc --version >/dev/null 2>/dev/null
    if [ $? != 0 ]; then
      echo "Warning: Linux-Intel has been requested but icc is not available. Using Linux-gfortran instead"
      arch=Linux-gfortran
    fi
  fi

  echo "running the OPS-LRS configure script"

  set -x
  ./configure\
    --aapp-prefix=${AAPP_INSTALL_DIR} \
    --xrcs-prefix=${XERCES_INSTALL_DIR} \
    --fftw-prefix=${FFTW_INSTALL_DIR} \
    --prefix=${OPSLRS_INSTALL_DIR} \
    --arch=${arch} \
    --optimize=normal \
    --site-id=${SITE_ID} \
    --nthreads=${NTHREADS} \
    && echo "OPS-LRS configure: OK" || { echo "ERROR: problem with OPS-LRS configure" ; exit 1 ; }
  set +x
  
  echo "Building OPS-LRS ..."
  make || { echo "OPS-LRS make failed"; exit 1; }
  echo "make: OK"
  echo "Running make install ..."
  make install || { echo "OPS-LRS make install failed"; exit 1; }

  echo "Finished OPS-LRS build"
  
fi  

############# OPS-LRS aux files 

if [ $item = 10 ]; then

  echo -e "\n** Installing OPS-LRS aux files  **"

  mkdir -p ${OPSLRS_INSTALL_DIR}

  cd $OPSLRS_INSTALL_DIR
  script=get_aux_files.sh
  url=https://nwp-saf.eumetsat.int/downloads/aapp_data_files/OPS-LRS/aux_data/
  [ -s $script ] || { echo "Downloading $script"; wget ${url}/${script}; }
  chmod +x $script

  dir=$OPSLRS_INSTALL_DIR/aux
  mkdir -p $dir

  echo "Downloading the aux files into $dir"
  ./get_aux_files.sh $dir

  echo "Finished downloading the aux files into $dir"
  echo "Note: you should run get_aux_files.sh periodically to check for updates,"
  echo "and monitor https://nwp-saf.eumetsat.int/site/forums/forum/aapp/announcements/"
fi  

############## kai 

if [ $item = 11 ]; then

  echo -e "\n** Installing kai  (${KAI_ZIP}) **"

  mkdir -p ${KAI_INSTALL_DIR}
  
  # Extract version, e.g. kai-1.12 from zip file kai_1_12_e8b74685d1.zip
  kai_version="kai-$(echo ${KAI_ZIP%_*} | cut -d'_' -f2- | tr '_' '.')"

  url=https://user.eumetsat.int/s3/eup-strapi-media/${KAI_ZIP}
  zipfile=${KAI_ZIP}
  kdir=${kai_version}
  if [ ! -x $KAI_INSTALL_DIR/$kdir/bin/kai ]; then
    echo "installing kai"
    cd $TAR
    if [ ! -s $zipfile ]; then
      echo "Downloading kai"
      wget --no-check-certificate $url || exit 1
    fi
    cd $BUILD
    [ -d $kdir ] || { echo "unpacking kai"; unzip ${TAR}/${zipfile}; }
    [ -d $kdir ] || { echo "$kdir not found, please check the kai zip file (${zipfile})"; exit 1; }
    cd ${kdir}

    #Set -std=c++11
    if [ $FORTRAN_COMPILER = gfortran ]; then
      set $(g++ --version) || { echo "Error: g++ is needed for kai but cannot be run"; exit 1; }
      version=${3%%.*}
      if [ $version -ge 11 ] && [[ "$CPPFLAGS" != *c++11* ]]; then
        export CPPFLAGS="${CPPFLAGS} -std=c++11"
      fi
    fi

    echo "configuring kai"
    chmod +x configure
    ./configure --prefix=${KAI_INSTALL_DIR}/${kdir} \
      && echo "kai configure: OK" || { echo "ERROR: problem with kai configure" ; exit 1 ; }
    echo "building kai"
    make || { echo "make failed for $kdir"; exit 1; }
    make install \
      && echo "make install kai: OK" || { echo "ERROR: problem with kai make install" ; exit 1 ; }
  else
    echo "found kai at $KAI_INSTALL_DIR/$kdir/bin"
  fi

  atovs_env_file=$AAPP_INSTALL_DIR/ATOVS_ENV8
  if [ -f ${atovs_env_file} ]; then
    source ${atovs_env_file}
    dir=${KAI_INSTALL_DIR}/${kdir}/bin
    if [[ $PATH != *${dir}* ]]; then
      echo "updating PATH in ${atovs_env_file}"
      P_OLD=${PATH#*metop-tools/bin}              #ignore the first part of string in the substitution
      P_NEW=${P_OLD}:${dir}
      sed -i "s|${P_OLD}|${P_NEW}|" ${atovs_env_file}
    fi
  fi
fi

############ netCDF-C

if [ $item = 12 ]; then

  echo -e "\n** Installing netCDF-C (version: ${NETCDF_C_VERSION}) **"

  [[ -s ${NETCDF_C_SYMLINK} ]] && rm -f ${NETCDF_C_SYMLINK}

  mkdir -p ${NETCDF_INSTALL_DIR}

  cd ${TAR}
  # e.g v4.8.1.tar.gz
  tarfile="v${NETCDF_C_VERSION}.tar.gz"
  url=https://github.com/Unidata/netcdf-c/archive/refs/tags
  dir=netcdf-c-${NETCDF_C_VERSION}
  [ -f ${dir}.tar.gz ] || wget ${url}/${tarfile}
  [ -f ${tarfile} ] && [ ! -f ${dir}.tar.gz ] && mv ${tarfile} ${dir}.tar.gz

  cd ${BUILD}
  [ -d ${dir} ] || tar -xf ${TAR}/${dir}.tar.gz
  cd ${dir}
  export LDFLAGS="-L${HDF5_INSTALL_DIR}/lib ${LDFLAGS}"
  export CPPFLAGS="-I ${HDF5_INSTALL_DIR}/include ${CPPFLAGS}"
  ./configure --prefix=${NETCDF_INSTALL_DIR} --disable-dap \
    && echo "netCDF-C configure: OK" || { echo "ERROR: problem with netCDF-C configure" ; exit 1 ; }
  make || { echo "ERROR: make failed for $dir"; exit 1; }
  make install \
    && echo "make install netCDF-C: OK" || { echo "ERROR: problem with netCDF-C make install" ; exit 1 ; }
  
  # Create a symlink to the netCDF-C installation directory
  if [[ ${NETCDF_INSTALL_DIR} != ${NETCDF_C_SYMLINK} ]]; then
    ln -s ${NETCDF_INSTALL_DIR} ${NETCDF_C_SYMLINK}
  fi

fi


############ netCDF Fortran library

if [ $item = 13 ]; then

  echo -e "\n** Installing netCDF-Fortran (version: ${NETCDF_F_VERSION}) **"

  [[ -s ${NETCDF_F_SYMLINK} ]] && rm -f ${NETCDF_F_SYMLINK}

  mkdir -p ${NETCDF_INSTALL_DIR}

  cd ${TAR}
  # e.g v4.5.3.tar.gz
  tarfile="v${NETCDF_F_VERSION}.tar.gz"
  url=https://github.com/Unidata/netcdf-fortran/archive/refs/tags
  dir=netcdf-fortran-${NETCDF_F_VERSION}
  [ -f ${dir}.tar.gz ] || wget ${url}/${tarfile}
  [ -f ${tarfile} ] && [ ! -f ${dir}.tar.gz ] && mv ${tarfile} ${dir}.tar.gz
  
  cd ${BUILD}
  [ -d ${dir} ] || tar -xf ${TAR}/${dir}.tar.gz
  cd ${dir}
  export LDFLAGS="-L${HDF5_INSTALL_DIR}/lib ${LDFLAGS}"
  export CPPFLAGS="-I ${HDF5_INSTALL_DIR}/include ${CPPFLAGS}"
  export LD_LIBRARY_PATH=${LD_LIBRARY_PATH:+$LD_LIBRARY_PATH:}${HDF5_INSTALL_DIR}/lib
  ./configure --prefix=${NETCDF_INSTALL_DIR} \
    && echo "netCDF-Fortran configure: OK" || { echo "ERROR: problem with netCDF-Fortran configure" ; exit 1 ; }
  make || { echo "ERROR: make failed for ${dir}"; exit 1; }
  make install \
    && echo "make install netCDF-Fortran: OK" || { echo "ERROR: problem with netCDF-Fortran make install" ; exit 1 ; }

  # Create a symlink to the netCDF-Fortran installation directory
  if [[ ${NETCDF_INSTALL_DIR} != ${NETCDF_F_SYMLINK} ]]; then
    ln -s ${NETCDF_INSTALL_DIR} ${NETCDF_F_SYMLINK}
  fi

fi

############ AAPP-AWS

if [ $item = 14 ]; then

  echo -e "\n** Installing AAPP-AWS (AAPP-version: ${AAPP_VERSION}) **"

  mkdir -p ${AAPP_INSTALL_DIR}

  cd $TAR
  tarfile=AAPP_${AAPP_VERSION}.tgz

  if [ ! -s $tarfile ]; then
    echo "Please put $tarfile in directory $TAR"
    exit 1
  fi

  cd $BUILD
  dir=${tarfile%.tgz}
  [ -d $dir ] || { echo "unpacking AAPP (includes AAPP-AWS)"; tar -xzf $TAR/$tarfile; }

  set -x
  cd ${dir}
  [ -d $ECCODES_INSTALL_DIR/lib ] && ECCODES_LIB=$ECCODES_INSTALL_DIR/lib \
                                  || ECCODES_LIB=$ECCODES_INSTALL_DIR/lib64
  ./configure_aapp_aws.sh \
    --fortran-compiler=${FORTRAN_COMPILER} \
    --hdf5-lib=${HDF5_INSTALL_DIR}/lib \
    --hdf5-inc=${HDF5_INSTALL_DIR}/include \
    --netcdf-lib=${NETCDF_INSTALL_DIR}/lib \
    --netcdf-inc=${NETCDF_INSTALL_DIR}/include \
    --eccodes-lib=${ECCODES_LIB} \
    --eccodes-inc=${ECCODES_INSTALL_DIR}/include \
    --prefix=${AAPP_AWS_INSTALL_DIR}
  status=$?
  set +x
  [[ ${status} -eq 0 ]] && echo "AAPP-AWS configure: OK" || { echo "Error: AAPP-AWS configure failed" ; exit 1 ; }

  echo "Building AAPP-AWS ..."
  AAPP_AWS_BUILD_DIR=${BUILD}/${dir}/AAPP-AWS
  cd ${AAPP_AWS_BUILD_DIR}/src
  echo "See logs files: ${PWD}/make-aapp-aws.out , ${PWD}/make-aapp-aws.err "
  make  >make-aapp-aws.out 2>make-aapp-aws.err || { echo "AAPP-AWS make failed"; exit 1; }  
  echo "See logs files: ${PWD}/make-install-aapp-aws.out , ${PWD}/make-install-aapp-aws.err "
  make install >make-install-aapp-aws.out 2>make-install-aapp-aws.err || { echo "AAPP-AWS make install failed"; exit 1; }

  echo "Finished AAPP-AWS build"

fi


cd ${CWD_ORIG}

date
echo -e "\nFinished running ${0}"
