#!/bin/bash

OPTIND=1

forced=false
adjoint=false
while getopts ":fa" opt
do
  case $opt in
    f) forced=true ;;
    a) adjoint=true ;;
    esac
done

shift $(($OPTIND - 1))

BOXMOX_PATH=${KPP_HOME}/boxmox

# sanity checks
if [ $# -ne 1 ]
then
  echo "Call with <mechanism name>."
  echo ""
  echo "Use -f to force removal of existing mechanism."
  echo "Use -a to adjoint version."
  echo ""
  exit 1
fi

mech_req=$1

# check if BOXMOX is correctly set up
validate_BOXMOX_installation || { echo "Validating BOXMOX installation failed."; exit 1; }

BOXMOX_MECH_PATH=${BOXMOX_PATH}/compiled_mechs

work_path=${KPP_HOME}/tmp_${mech_req}_${RANDOM}_BOXMOX

mkdir -p ${BOXMOX_MECH_PATH}

mech_name=$(basename ${mech_req})
mech_path=${BOXMOX_MECH_PATH}/${mech_name}
mech_exe=${mech_name}.exe

if $adjoint
then
  mech_path=${mech_path}_adjoint
  mech_exe=${mech_name}_adjoint.exe
fi

# prerequisite check
hash kpp >/dev/null 2>&1  || { echo "No working KPP found."; exit 1; }

[ -f $KPP_HOME/examples/${mech_name}.kpp ] || { echo "${mech_name}.kpp does not exist."; exit 1; }
[ -f $KPP_HOME/models/${mech_name}.eqn ]   || { echo "${mech_name}.eqn does not exist."; exit 1; }
[ -f $KPP_HOME/models/${mech_name}.def ]   || { echo "${mech_name}.def does not exist."; exit 1; }
[ -f $KPP_HOME/models/${mech_name}.spc ]   || { echo "${mech_name}.spc does not exist."; exit 1; }

$forced && { rm -rf ${mech_path}; }
[ -f ${mech_path}/${mech_exe} ] && { echo "${mech_name} has already been prepared, use -f to force recreating it."; exit 0; }

echo "All necessary files and programs found."

rm -rf ${mech_path} ${work_path}
mkdir -p ${work_path}

cd ${work_path}

cp $KPP_HOME/examples/${mech_name}.kpp ${mech_name}.kpp

if $adjoint
then
  echo "Preparing adjoint config."
  mv ${mech_name}.kpp ${mech_name}.kpp_TMP
  sed -e 's:\(#DRIVER.*\)/boxmox:\1/boxmox_adjoint:' -e 's:\(#INTEGRATOR.*\):\1_adj:' -e 's:\(#HESSIAN.*OFF\):#HESSIAN ON:' < ${mech_name}.kpp_TMP > ${mech_name}.kpp
fi

echo "Running KPP."

kpp ${mech_name}.kpp &> kpp.log

[ -f ${work_path}/Makefile_${mech_name} ] || {
  echo ""
  echo "${mech_name} could not be KPP'ed."
  echo ""
  echo "Check ${work_path}/kpp.log for errors."
  echo "Maybe you need to revise your mechanism description"
  echo "files (.eqn, .def, .spc) in $KPP_HOME/models?"
  echo ""
  exit 1
}

echo "'Make'ing the model."

make -f Makefile_${mech_name} &> compile.log

if $adjoint
then
  mv ${work_path}/${mech_name}.exe ${work_path}/${mech_exe}
fi

[ -f ${work_path}/${mech_exe} ] || {
  echo ""
  echo "${mech_name} could not be compiled."
  echo ""
  echo "Check"
  echo "  ${work_path}/compile.log"
  echo "for errors."
  echo ""
  echo "Maybe your inlined code in ${mech_name}.def in"
  echo "  $KPP_HOME/models"
  echo "is not valid Fortran?"
  echo ""
  echo "The compiler options used might not work on your machine."
  echo "Try changing them (FOPT_GFORTRAN) in"
  echo "  ${work_path}/Makefile_${mech_name}"
  echo "and then update the parameters in"
  echo "  ${KPP_HOME}/util/Makefile.f90"
  echo "to make the changes permanent."
  echo ""
  exit 1
}

cd ..

mv ${work_path} ${mech_path}
echo "Successfully created ${mech_exe}."

exit 0
