#! /usr/bin/env bash
#
# This script contains all the necessary steps to recreate the
# autotools files to build the project.
#
# Copyright  (C)  2021  Thomas Jahns <jahns@dkrz.de>
#
# Version: 1.0
# Author: Thomas Jahns <jahns@dkrz.de>
# Keywords: autotools autogen autoconf libtool automake
# Maintainer: Thomas Jahns <jahns@dkrz.de>
# URL: https://swprojects.dkrz.de/redmine/projects/scales-ppm
#
# Redistribution and use in source and binary forms, with or without
# modification, are  permitted provided that the following conditions are
# met:
#
# Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# Neither the name of the DKRZ GmbH nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
# OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
set -e

# this should guarantee reproducible results from automake runs
export PERL_HASH_SEED=0

if [[ -z "${LIBTOOLIZE:-}" ]]; then
  case $(uname -s) in
    Darwin)
      LIBTOOLIZE=glibtoolize
      if [[ -z "${SED+set}" ]] && command -v gsed >/dev/null; then
        SED=gsed
      fi
      ;;
    *)
      LIBTOOLIZE=libtoolize
      ;;
  esac
  # make sure autoreconf calls the same libtoolize:
  export LIBTOOLIZE
fi

SED=${SED-sed}
if sed_version=$($SED --version 2>/dev/null) && [[ $sed_version = *GNU\ sed* ]]; then
  sed_inplace_options=('-i')
elif $SED -E </dev/null 2>/dev/null >/dev/null ; then
  # assume modern FreeBSD sed
  sed_inplace_options=('-i' '')
else
  printf '%s\n' 'Cannot find sed able to operate in place.' \
    'Please provide full path to GNU or FreeBSD sed in SED environment variable.' \
    >&2
  exit 1
fi

$LIBTOOLIZE --force --copy
autoreconf -i --force
libtoolversion=$($LIBTOOLIZE --version \
                      | ${SED} -e 's/^'"${LIBTOOLIZE##*/}"' \(([^)]*) \)\{0,1\}\([0-9.]*\)/\2/;q')
declare -a patches
case "$libtoolversion" in
  (2.4.6|2.4.7)
    patches=("contrib/00nagfor-libtool-patch/nagfor-libtool-${libtoolversion}.patch" \
      contrib/01aix-deplib-rpath-patch/aix-deplib-libtool.patch \
      contrib/03ltmain-ld-groups-patch/ltmain-ld-groups-libtool-2.4.6.patch \
      contrib/04ltmain-xlinker-patch/ltmain-xlinker-patch.patch \
      contrib/05macos-nagfor-patch/macos-nagfor-libtool-2.4.6.patch \
      contrib/06ltmain_nag_pthread-patch/ltmain_nag_pthread-libtool-2.4.6.patch \
      contrib/07ltmain-early-xcompile-patch/ltmain-early-xcompile-libtool-2.4.6.patch \
      contrib/08ltmain-parallel-printf-patch/ltmain-parallel-printf-libtool-2.4.6.patch \
      contrib/09debian-no-overlink-patch/deplib_binary.patch \
      contrib/09debian-no-overlink-patch/link_all_deplibs.patch \
      contrib/10ltmain-ld-positional-wl-patch/ltmain-ld-positional-wl-libtool-2.4.6.patch)
    ;;
  (2.4.2)
    patches=(contrib/00nagfor-libtool-patch/nagfor-libtool-2.4.2.patch \
      contrib/01aix-deplib-rpath-patch/aix-deplib-libtool.patch \
      contrib/02nagfor53-shared-patch/nagfor53-shared.patch \
      contrib/03ltmain-ld-groups-patch/ltmain-ld-groups-libtool-2.4.2.patch \
      contrib/04ltmain-xlinker-patch/ltmain-xlinker-patch.patch \
      contrib/05macos-nagfor-patch/macos-nagfor-libtool-2.4.2.patch \
      contrib/06ltmain_nag_pthread-patch/ltmain_nag_pthread-libtool-2.4.2.patch \
      contrib/08ltmain-parallel-printf-patch/ltmain-parallel-printf-libtool-2.4.2.patch \
      contrib/09debian-no-overlink-patch/deplib_binary-libtool-2.4.2.patch \
      contrib/09debian-no-overlink-patch/link_all_deplibs-libtool-2.4.2.patch \
      contrib/10ltmain-ld-positional-wl-patch/ltmain-ld-positional-wl-libtool-2.4.2.patch)
    ;;
esac
for patch in "${patches[@]}"; do
  echo "applying $patch" >&2
  patch -p1 <"$patch"
done
autoreconf -i
# fix timestamps of the header templates
${AUTOHEADER-autoheader} --force
# shellcheck disable=SC2086
find . -name Makefile.in -exec $SED "${sed_inplace_options[@]}" \
  -e 's/[	 ][	 ]*$//' \{\} +
\rm -f config/ltmain.sh.orig m4/libtool.m4.orig

if [[ -z "${DL_CMD-}" ]]; then
  if command -v wget >/dev/null ; then
    DL_CMD=(wget -nv -o /dev/null -O)
  elif command -v curl >/dev/null ; then
    DL_CMD=(curl --location -s -S -o)
  fi
else
  # shellcheck disable=SC2128
  read -r -a DL_CMD <<< "${DL_CMD}"
fi

cnf_age_tolerance=$((24*3600*31))
cnf_cache_dir=${cnf_cache_dir-"${HOME}/.config/autotools/cache"}
[[ -d "${cnf_cache_dir}" ]] || mkdir -p "${cnf_cache_dir}"
cnf_files=(config/config.guess config/config.sub)
cnf_urls=('https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD' \
  'https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD')

cnf_get_timestamp()
{
  if [[ -f "$2" ]] && timestamp=$(grep '^timestamp=' "$2" 2>/dev/null); then
    timestamp=${timestamp#timestamp=\'}
    timestamp=${timestamp%\'}
  else
    timestamp='1970-01-01'
  fi
  if expr "$timestamp" : '[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}$' >/dev/null; then
    timestamp+=' 00:00:00'
  fi
  timestamp=$(date +%s -u -d "${timestamp}" 2>/dev/null \
              || date -j -u -f '%Y-%m-%d %H:%M:%S' "${timestamp}" +%s)
  typeset -g "$1=$timestamp"
}

now=$(date -u '+%s')
for ((i=0 ; i < ${#cnf_files[@]} ; ++i)); do
  cnf_file=${cnf_files[i]}
  cnf_cache_file="$cnf_cache_dir/${cnf_file#*/}"
  timestamp_autotools=0
  cnf_get_timestamp timestamp_autotools "$cnf_file"
  #  timestamp_cache=0
  #  cnf_get_timestamp timestamp_cache "$cnf_cache_file"
  if [[ -f "$cnf_cache_file" ]]; then
    cnf_cache_retrieve_time=$(date -r "$cnf_cache_file" -u +'%s')
  else
    cnf_cache_retrieve_time=0
  fi
  if (( cnf_cache_retrieve_time + cnf_age_tolerance >= now )); then
    if (( cnf_cache_retrieve_time > timestamp_autotools )); then
      cp -p "$cnf_cache_file" "$cnf_file"
    fi
  else
    "${DL_CMD[@]}" "${cnf_file}" "${cnf_urls[i]}" \
      || "${DL_CMD[@]}" "${cnf_file}" "${cnf_urls[i]}"
    cp "$cnf_file" "$cnf_cache_file"
  fi
done

if [ -x scripts/recreate-testsuite.sh ]; then
  scripts/recreate-testsuite.sh
fi

#
# to test if this succeeded, one can run
# diff -x autom4te.cache -x .git -ur orig/<project> new/<project> 2>&1 | less
# if a known good checkout is at orig/<project> and a newly reconfigured
# tree is at new/<project>
#
# Local Variables:
# mode: sh
# license-project-url: "https://swprojects.dkrz.de/redmine/projects/scales-ppm"
# license-default: "bsd"
# End:
#
