#!/bin/bash

## Copyright (C) 2016 Susi Lehtola
## Copyright (C) 2016 Julien Bect <jbect@users.sourceforge.net>
##
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 2 of the License, or
## (at your option) any later version.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program; if not, see <http://www.gnu.org/licenses/>.

## boostrap generates 'configure.ac', 'config.h.in' and 'configure' as follows:
##
## configure.ac.in
## buildgsl_sf.sh
##
##   |
##   | bootstrap
##   v
##
## configure.ac
##
##   |
##   | autoheader  (called by bootstrap)
##   | autoconf    (called by bootstrap)
##   v
##
## config.h.in
## configure
##

echo "dnl --- DO NOT EDIT ---" > configure.ac
echo "dnl configure.ac is generated by bootstrap from configure.ac.in." >> configure.ac
echo "dnl Edit configure.ac.in and reprocess instead of modifying ./configure.ac." >> configure.ac
echo "" >> configure.ac

cat configure.ac.in >> configure.ac
rm -f config.h.in
rm -f INDEX.tmp

# Get list of function names defined in the build script
funcnames=($(grep "export octave_name=" buildgsl_sf.sh | awk -F= '{print $NF}'))
gslfuncs=($(grep "export    funcname=" buildgsl_sf.sh | awk -F= '{print $NF}'))
if(( ${#funcnames[@]} != ${#gslfuncs[@]} )); then
    echo "Parse error in bootstrap."
    exit
fi

# Extract list of deprecated functions from the build script
echo "# This file is generated by bootstrap" > DEPRECATED
grep "DEPRECATED: " buildgsl_sf.sh | sed -e "s/#\s*DEPRECATED:\s*//" >> DEPRECATED

for((i=0;i<${#funcnames[@]};i++)); do

    # Add AC_CHECK_FUNCS statement in configure.ac
    echo -n "AC_CHECK_FUNCS([${gslfuncs[i]}],," >> configure.ac
    DEPREC_INFO=`grep ${funcnames[i]} DEPRECATED`
    if [ -z "$DEPREC_INFO" ]; then
        # Non-deprecated functions are marked as missing when not found
        # (but deprecated functions are just silently ignored)
        echo -n "[GSL_MISSING=\"\${GSL_MISSING} ${funcnames[i]}\"]" >> configure.ac
    fi
    echo ")" >> configure.ac

    if [[ ${funcnames[i]} =~ ^gsl_.* ]]; then
        # Add an entry in INDEX.tmp (unsorted index file, at this point)
        echo " ${funcnames[i]}" >> INDEX.tmp
    fi

done

# Create INDEX file
rm -f INDEX
cat >> INDEX <<EOF
math >> Mathematics
Special functions
EOF
sort INDEX.tmp >> INDEX
cat >> INDEX <<EOF
Support
 gsl_sf
EOF
mv INDEX ..
rm -f INDEX.tmp

# Finish configure.ac
cat >> configure.ac <<EOF

if test -z "\$GSL_MISSING"; then
  AC_MSG_RESULT([GSL special functions: all available])
else
  AC_MSG_WARN([Some GSL special functions are missing: \$GSL_MISSING])
fi

AC_OUTPUT([Makefile])

EOF

autoheader
chmod 0755 config.h.in

autoconf
chmod 0755 configure

# Generate 'simple' template files for gsl_sf_* functions
GT="./generate_template.sh"

${GT} double D_D.template.cc
${GT} double double DD_D.template.cc
${GT} double double double DDD_D.template.cc
${GT} double double double double DDDD_D.template.cc
${GT} double double double double mode DDDDM_D.template.cc
${GT} double mode DM_D.template.cc
${GT} double double mode DDM_D.template.cc
${GT} double double double mode DDDM_D.template.cc
${GT} int I_D.template.cc
${GT} int double ID_D.template.cc
${GT} double int DI_D.template.cc
${GT} int int double IID_D.template.cc
${GT} int double double IDD_D.template.cc
${GT} int int double double IIDD_D.template.cc
${GT} uint U_D.template.cc
${GT} uint uint UU_D.template.cc
${GT} int int int int int int IIIIII_D.template.cc
${GT} int int int int int int int int int IIIIIIIII_D.template.cc

# Generate template files for gsl_sf_*_array
GTA="./generate_array_template.sh"

# Bessel function type, array length is determined by l value which starts from l=0
${GTA} int+ double "arg1+1" 1 LD_D_array.template.cc
${GTA} int+ double "arg1+1" 2 LD_DD_array.template.cc
${GTA} int+ double double "arg1+1" 1 LDD_D_array.template.cc
${GTA} int+ double double "arg1+1" 2 LDD_DD_array.template.cc

# Bessel function type, array length is determined by lmin and lmax values that start from l=0
${GTA} int+ int+ double "arg2-arg1+1" 1 LLD_D_array.template.cc
${GTA} int+ int+ double "arg2-arg1+1" 2 LLD_DD_array.template.cc

# Legendre type, array length is determined by l value
${GTA} int+ int+ double "arg1+1" 1 LID_D_array.template.cc
${GTA} int+ int+ double "arg1+1" 2 LID_DD_array.template.cc

# Legendre array templates
${GTA} legnorm size_t double double "arg2" 1 NSDD_D_array.template.cc
${GTA} legnorm size_t double double "arg2" 2 NSDD_DD_array.template.cc
${GTA} legnorm size_t double double "arg2" 3 NSDD_DDD_array.template.cc

# Generate gsl_sf.cc
./buildgsl_sf.sh
