#!/bin/bash
set -e

TOP_DIR="$( cd "$( dirname "$0" )" && pwd )"
cd ${TOP_DIR}

################################################################################
# Evironment Variables

# BUILD_MODE:                     release/debug
# BUILD_DIR:                      build(default)
# TARGET_MLU_ARCH:                CNFATBIN/MLU590
# TARGET_CPU_ARCH:                x86_64-linux-gnu
# TARGET_C_COMPILER:              C comppiler full-path
# TARGET_CXX_COMPILER:            CXX comppiler full-path
# STRIP                           strip tool path
################################################################################
BUILD_MODE=${BUILD_MODE:-release}
BUILD_DIR="${BUILD_DIR:-build}"
BUILD_JOBS=${BUILD_JOBS:-32}
TARGET_MLU_ARCH=${TARGET_MLU_ARCH:-CNFATBIN}
TARGET_CPU_ARCH=${TARGET_CPU_ARCH:-$(uname -m)-linux-gnu}
TARGET_C_COMPILER=${TARGET_C_COMPILER:-gcc}
TARGET_CXX_COMPILER=${TARGET_CXX_COMPILER:-g++}
STRIP="${STRIP}" # empty by default, check later

# to forward variable to other scripts
export BUILD_DIR

################################################################################
# Shell Common Functions
################################################################################
check_deb_package() {
    if [ -z "$(dpkg -l | grep ${1})" ]; then
        echo "-- Please sudo apt install ${1}"
        exit -1
    fi
}

check_rpm_package() {
    if [ -z "$(rpm -qa | grep ${1})" ]; then
        echo "-- Please sudo yum install ${1}"
        exit -1
    fi
}

usage () {
    echo "USAGE: build.sh <options>"
    echo
    echo "       If need specify neuware path, please:"
    echo "         export NEUWARE_HOME=/path/of/your/neuware"
    echo
    echo "OPTIONS:"
    echo "      -h, --help                     Print usage"
    echo "      <null>                         If no --mluxxx specified, default arch is cnfatbin which contain all mlu arch"
    echo "      --mlu590                       Build for target product MLU590: __BANG_ARCH__ = 592"
    echo "                                                                      cncc --bang-mlu-arch=mtp_592, cnas --mlu-arch mtp_592"
    echo "      -d, --debug                    Build test case with debug mode"
    echo "      -v, --verbose                  Build with verbose output"
    echo "      -j, --jobs=*                   Build parallel jobs"
    echo "      --cache                        Build without deleting BUILD_DIR contents first"
}

################################################################################
# Build Main Entry
################################################################################
# 1. Check cmake tool for build, cmake-3.23.1 is recommended
if [ -f "/etc/os-release" ]; then
    source /etc/os-release
    if [[ "${NAME}" == Ubuntu* ]] || [[ "${NAME}" == Debian* ]]; then
        check_deb_package cmake
        CMAKE=cmake
    elif [[ "${NAME}" == CentOS* ]] || [[ "${NAME}" == Kylin* ]]; then
        if [[ "${VERSION_ID}" == 7 ]]; then
            check_rpm_package cmake3
            CMAKE=cmake3
        else
            check_rpm_package cmake
            CMAKE=cmake
        fi
    elif [[ "${NAME}" == Anolis* ]];then
        check_rpm_package cmake
	CMAKE=cmake
    else
        echo "-- Not support build on this os!"
        exit -1
    fi
else
    echo "-- Not support build on this os!"
    exit -1
fi

# 2. Create build dir
if [ ! -d "$BUILD_DIR" ]; then
    mkdir "$BUILD_DIR"
fi

# 3. Handle build options
cmdline_args=$(getopt -o h,d,v,j: --long help,debug,verbose,jobs:,mlu590,cache -n 'build.sh' -- "$@")
eval set -- "$cmdline_args"
if [ $? != 0 ]; then echo "Unknown options, use -h or --help" >&2 ; exit -1; fi
if [ $# != 0 ]; then
  while true; do
    case "$1" in
      --mlu590)
          TARGET_MLU_ARCH="mtp_592"
          shift
          ;;
      -h | --help)
          usage
          exit 0
          ;;
      -d | --debug)
          BUILD_MODE="debug"
          echo "-- Using debug mode."
          shift
          ;;
      -v | --verbose)
          BUILD_VERBOSE="VERBOSE=1"
          shift
          ;;
      -j | --jobs)
          shift
          BUILD_JOBS=$1
          shift
          ;;
      --cache)
          FLAG_KEEP_CACHE=1
          shift
          ;;
      --)
          shift
          break
          ;;
      *)
          echo "-- Unknown options ${1}, use -h or --help"
          usage
          exit -1
          ;;
    esac
  done
fi

# 5. Check NEUWARE_HOME and cncc
if [ ! -z "${NEUWARE_HOME}" ]; then
  echo "-- using NEUWARE_HOME = ${NEUWARE_HOME}"
else
  echo "-- NEUWARE_HOME is null, refer README.md to prepare NEUWARE_HOME environment."
  exit -1
fi

# 6. Check device compiler
export PATH="${NEUWARE_HOME}/bin":$PATH
export LD_LIBRARY_PATH="${NEUWARE_HOME}/lib64":$LD_LIBRARY_PATH
if [ -z $(which cncc) ]; then
  echo "-- ERROR: cannot find cncc"
  exit -1
fi
cncc --version || ( echo "-- ERROR: cncc is not for current CPU target" && exit -1 )
echo "-- cncc: $(which cncc)"

# Check host compiler
## check compiler version and consider activate devtoolset for CentOS 7
if [ "$OS_RELEASE_ID" = "centos" -a "$OS_RELEASE_VERSION_ID" = "7" ]; then
  if [ ! -f "/opt/rh/devtoolset-7/enable" ]; then
    echo "You are using CentOS 7 but without 'devtoolset-7' installed."
    echo "Please install devtoolset-7 or gnu-g++ that verion >= 5."
    sleep 2
  else
    source /opt/rh/devtoolset-7/enable && echo "devtoolset-7 activated" \
    || echo "devtoolset-7 has installed on your server, but source failed."
  fi
fi
if [[ "$(g++ --version | head -n1 | awk '{ print $3 }' | cut -d '.' -f1)" -lt "5" ]]; then
  echo "we do not support g++<5, try to use higher version"
  exit 1
fi
TARGET_C_COMPILER=$(which gcc)
TARGET_CXX_COMPILER=$(which g++)
echo "-- TARGET_C_COMPILER: " ${TARGET_C_COMPILER}
echo "-- TARGET_CXX_COMPILER: " ${TARGET_CXX_COMPILER}
export CC=$(basename ${TARGET_C_COMPILER})
export CXX=$(basename ${TARGET_CXX_COMPILER})

################################################################################
# Project Build
################################################################################
CMAKE_EXTRA_OPTIONS=()

SOURCE_DIR=${TOP_DIR}
pushd ${BUILD_DIR}
  if [[ -z "${FLAG_KEEP_CACHE}" ]]; then
    echo "Remove cmake cache ${PWD}"
    rm -rf ./*
  fi
  ${CMAKE} -DCMAKE_BUILD_TYPE="${BUILD_MODE}" \
           -DNEUWARE_HOME="${NEUWARE_HOME}" \
           -DTARGET_MLU_ARCH="${TARGET_MLU_ARCH}" \
           -DTARGET_CPU_ARCH="${TARGET_CPU_ARCH}" \
           -DCMAKE_C_COMPILER="$(basename ${TARGET_C_COMPILER})" \
           -DCMAKE_CXX_COMPILER="$(basename ${TARGET_CXX_COMPILER})" \
           -DCMAKE_STRIP="${STRIP}" \
           ${CMAKE_EXTRA_OPTIONS[@]} ${SOURCE_DIR}
popd
${CMAKE} --build ${BUILD_DIR} -- ${BUILD_VERBOSE} -j${BUILD_JOBS}
