#!/bin/bash


# FUNCTIONS DECLARATION
#---------------------------------------------------
show_opts() {
  cat <<EOT

  Tools enablers:
    --ompss                                 Enables worker compilation with OmpSs Mercurium compiler
                                            Default: Disabled
    --cuda                                  Enables worker compilation with CUDA compilation flags
                                            Default: Disabled
    --opencl                                Enables worker compilation with openCL compilation flags
                                            Default: Disabled
    --with_ompss=<ompss_installation_path>  Enables worker compilation with OmpSs Mercurium compiler installed in a certain location
                                            Default: Disabled
    --mercurium_flgas="flags"               Specifies extra flags to pass to the mercurium compiler
                                            Default: Empty
    --with_cuda=<cuda_installation_path>    Enables worker compilation with CUDA installed in a certain location
                                            Default: Disabled
    --with_opencl=<ocl_installation_path>   Enables worker compilation with openCL installed in a certain location
                                            Default: Disabled
    --opencl_libs="libs"		    Specifies extra opencl libraries locations
					    Default: Empty
EOT
}

usage() {
  exitValue=$1

  cat <<EOT
Usage: $0 [options] application_name application_arguments

* Options:
  General:
    --help, -h                              Print this help message

    --opts                                  Show available options

    --version, -v                           Print COMPSs version
EOT
  show_opts
  exit "$exitValue"
}

show_version() {
  echo "COMPSs version 2.3 Daisy"
  echo " "
}

# Displays parsing arguments errors
display_error() {
  local error_msg=$1

  echo "$error_msg"
  echo " "

  usage 1
}

# Displays runtime/application errors
error_msg() {
  local error_msg=$1

  # Display error
  echo
  echo "$error_msg"
  echo

  # Exit
  exit 1
}

get_args() {
  # Parse COMPSs Options
  while getopts hvgtmd-: flag; do
    # Treat the argument
    case "$flag" in
      h)
        # Display help
        usage 0
        ;;
      v)
        # Display version
        show_version
        exit
        ;;
      -)
        # Check more complex arguments
        case "$OPTARG" in
          help)
            # Display help
            usage 0
            ;;
          version)
            # Show version
            show_full_version
            exit 0
            ;;
          opts)
            # Display help
            show_opts
            exit 0
            ;;
	  debug)
            debug=1
	    ;;
          instrument)
            instrument=1
            ;;
          ompss)
            ompss_enabled=1
            ;;
          cuda)
            cuda_enabled=1
            ;;
          opencl)
            opencl_enabled=1
            ;;
          with_ompss=*)
            ompss_enabled=1
            ompss_prefix=${OPTARG//with_ompss=/}
            ;;
          mercurium_flags=*)
            ompss_flags=${OPTARG//mercurium_flags=/}
            ;;
          with_cuda=*)
            cuda_enabled=1
            cuda_prefix=${OPTARG//with_cuda=/}
            ;;
          with_opencl=*)
            opencl_enabled=1
            opencl_prefix=${OPTARG//with_opencl=/}
            ;;
          opencl_libs=*)
            opencl_libraries=${OPTARG//opencl_libs=/}
            ;;
          *)
            # Flag didn't match any patern. Raise exception
            display_error "Bad argument: $OPTARG"
            ;;
        esac
        ;;
      *)
        # Flag didn't match any patern. End of COMPSs flags
        break
        ;;
    esac
  done
  # Shift COMPSs arguments
  shift $((OPTIND-1))

  # Parse application name
  if [[ $# -eq 0 ]]; then
    display_error "Error application name not specified"
  else
    other_args=$*
  fi
}

debug=0
instrument=0
get_args "$@"

echo "*---------------------------------------------------------------------*"
echo "*                                                                     *"
echo "*               BSC - Barcelona Supercomputing Center                 *"     
echo "*                          COMP Superscalar                           *"      
echo "*                                                                     *" 
echo "*                  C/C++ Applications - BUILD SCRIPT                  *"      
echo "*                                                                     *"
echo "*  More information at COMP Superscalar Website: http://compss.bsc.es *"
echo "*                                                                     *"
echo "*  Support: support-compss@bsc.es                                     *"
echo "*                                                                     *"        
echo "*  Dependencies: bash, csh                                            *"
echo "*                                                                     *"
echo "*---------------------------------------------------------------------*"
echo ""

if [ $debug -eq 1 ]; then
   export CPPFLAGS="$CPPFLAGS -DDEBUG_BINDING"
   ompss_flags="${ompss_flags} --debug"
fi

if [ $instrument -eq 1 ]; then
  ompss_flags="${ompss_flags} --instrument"
fi

# Setting Java folder
libjava=$(find "${JAVA_HOME}"/jre/lib/ -name libjvm.so | head -n 1)
if [ -z "$libjava" ]; then
  libjava=$(find "${JAVA_HOME}"/jre/lib/ -name libjvm.dylib | head -n 1)
  if [ -z "$libjava" ]; then
    display_error "${JAVA_JRE_ERROR}"
  fi
fi
LIBJAVAFOLDER=$(dirname "$libjava")
export LIBJAVAFOLDER

# GS HOME
if [ -z "$CS_HOME" ]; then
  if [ -z "$COMPSS_HOME" ]; then
    export CS_HOME=/opt/COMPSs/Bindings/c
  else
    export CS_HOME=$COMPSS_HOME/Bindings/c
  fi
fi
export COMPSSGEN=$CS_HOME/bin/compss_generator

# Application src compilation
if [ -d "./src" ]; then
  (
  cd ./src || exit 1
  make)
  ev=$?
  if [ $ev -ne 0 ]; then 
    echo " "
    echo "Building user application failed, please check errors above!"
    exit $ev
  fi
fi
# Building Master and Worker
export CC="gcc"
export CXX="g++"
# shellcheck disable=SC2086
"$CS_HOME"/bin/compss_build build master ${other_args}
ev=$?
if [ $ev -ne 0 ]; then
  echo " "
  echo "Building binding failed, please check errors above!"
  exit $ev
fi
if [ "${ompss_enabled}" != "" ]; then
  # Flag is defined, check value
  if [ ${ompss_enabled} == 1 ]; then
    export CC="mcc"
    export CFLAGS="$CFLAGS --ompss ${ompss_flags} $COMPSS_MCXX_FLAGS"
    export CXX="mcxx"
    export CXXFLAGS="$CXXFLAGS --ompss ${ompss_flags} $COMPSS_MCXX_FLAGS"
    export CPPFLAGS="$CPPFLAGS -DOMPSS_ENABLED"
  fi
fi
if [ "${cuda_enabled}" != "" ]; then
  # Flag is defined, check value
  if [ ${cuda_enabled} == 1 ]; then
    export LIBS="$LIBS -lcudart"
    if [ -z "${cuda_prefix}" ]; then
        if [ -z "$CUDA_HOME" ]; then
           export CUDA_HOME=/usr/local/cuda/
        fi
    else
        export CUDA_HOME=${cuda_prefix}
    fi
    export PATH=$PATH:${CUDA_HOME}/bin
    export LDFLAGS="--cuda $LDFLAGS -L${CUDA_HOME}/lib64"
    export CFLAGS="$CFLAGS --cuda"
    export CXXFLAGS="$CXXFLAGS --cuda"
  fi
fi
if [ "${opencl_enabled}" != "" ]; then
  # Flag is defined, check value
  if [ ${opencl_enabled} == 1 ]; then
    # Altera ocl flags export LDADD="$LDADD -L/home/altera/16.0.2/hld/linux64/lib -L/opt/intel_deliverable_WW49_16/bdw_fpga_pilot_opencl_bsp_v1.0/host/linux64/lib    -lalterahalmmd -laltera_qpi_mmd  -laalrt  -L/opt/aalsdk/aalsdk-5.0.2/lib"    
    export LDFLAGS="--opencl $LDFLAGS ${opencl_libraries}"
    export CFLAGS="$CFLAGS --opencl"
    export CXXFLAGS="$CXXFLAGS --opencl"
  fi
fi

# shellcheck disable=SC2086
"$CS_HOME"/bin/compss_build build worker ${other_args}
ev=$?
if [ $ev -ne 0 ]; then
    echo " "
    echo "Building binding failed, please check errors above!"
    exit $ev
fi

# End
echo ""
echo "*---------------------------------------------------------------------*"
echo "*                                                                     *"
echo "*  Application successfully built!!!                                  *"
echo "*                                                                     *"
echo "*  More information at COMP Superscalar website: http://compss.bsc.es *"
echo "*                                                                     *"        
echo "*---------------------------------------------------------------------*"

