#!/bin/bash
################################################################################
# Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The OpenAirInterface Software Alliance licenses this file to You under
# the Apache License, Version 2.0  (the "License"); you may not use this file
# except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#-------------------------------------------------------------------------------
# For more information about the OpenAirInterface (OAI) Software Alliance:
#      contact@openairinterface.org
################################################################################
# file build_upf
# brief
# author Lionel Gauthier
# company Eurecom
# email: lionel.gauthier@eurecom.fr
#

set -o pipefail

THIS_SCRIPT_PATH=$(dirname $(readlink -f $0))

## initialize git submodules
pushd ${THIS_SCRIPT_PATH}/../..
if [ -d .git ] && [ -f .gitmodules ]; then
  echo "Synchronizing the Git Sub-Modules"
  git submodule status | while read -r line ; do
    moduleName=`echo $line | awk '{print $2}'`
    gitReference=`echo $line | awk '{print $3}'`
    if [[ -z "$gitReference" ]]; then
      echo "$moduleName looks empty!"
      git submodule update --init --recursive $moduleName
    fi
  done
  git submodule --quiet foreach 'echo "${path} is synchronized or in edition"'
fi
popd

INSTALL_DIR=/usr/local/bin
################################
# include helper functions
################################
source $THIS_SCRIPT_PATH/build_helper.upf

function help()
{
  echo_error " "
  echo_error "Usage: build_upf [OPTION]..."
  echo_error "Build the UPF executable."
  echo_error " "
  echo_error "Options:"
  echo_error "Mandatory arguments to long options are mandatory for short options too."
  echo_error "  -b, --build-type                          Build type as defined in cmake, allowed values are: Debug Release RelWithDebInfo MinSizeRel"
  echo_error "  -c, --clean                               Clean the build generated files: config, object, executable files (build from scratch)"
  echo_error "  -f, --force                               No interactive script for installation of software packages."
  echo_error "  -h, --help                                Print this help."
  echo_error "  -I, --install-deps                        Check installed software necessary to build and run UPF (support $SUPPORTED_DISTRO)."
  echo_error "  -i, --install-min-deps                    Check installed software necessary to run a statically linked UPF (support $SUPPORTED_DISTRO)."
  echo_error "  -j, --jobs                                Multiple jobs for compiling."
  echo_error "  -v, --verbose                             Build process verbose."
  echo_error "  -V, --Verbose                             CMake only build process verbose, display compilation warnings and errors."
  echo_error "  -l, --lttng                               Build variant that will also include LTTNG" 
  echo_error " "
}

function main()
{
  local -i clean=0
  local -i force=0
  local -i debug=0
  local -i verbose=0
  local -i var_check_install_min_deps=0
  local -i var_check_install_deps=0
  local    cmake_args=" "
  export make_args=" "


  until [ -z "$1" ]
    do
    case "$1" in
      -b | --build-type)
        list_include_item "Debug Release RelWithDebInfo MinSizeRel" $2
        [[ $? -ne 0 ]] && echo_error "Build type $2 not recognized" && return $?
        cmake_args="$cmake_args -DCMAKE_BUILD_TYPE=$2"
        list_include_item "Debug" $2
        [[ $? -ne 0 ]] && debug=1
        shift 2;
        ;;
      -c | --clean)
        clean=1
        echo "Clean the build generated files (build from scratch)"
        shift;
        ;;
      -l | --lttng)
        check_platform_for_lttng
        output=$?
        if [[ $output == 1 ]]; then
          cmake_args="$cmake_args -DUSE_LTTNG=ON"
          echo ${cmake_args}
        fi
        shift;
        ;;
      -f | --force)
        force=1
        echo "Force set (no interactive)"
        shift;
        ;;
      -h | --help)
        help
        shift;
        return 0
        ;;
      -I | --install-deps)
        echo "Check installed software necessary to build and run UPF (support $SUPPORTED_DISTRO):"
        set_openair_env
        var_check_install_deps=1
        shift;
        ;;
      -i | --install-min-deps)
        echo "Check installed software necessary to run UPF (support $SUPPORTED_DISTRO):"
        set_openair_env
        var_check_install_min_deps=1
        shift;
        ;;
      -j | --jobs)
        make_args="$make_args -j`nproc`"
        shift;
        ;;
      -v | --verbose)
        echo "Make build process verbose"
        cmake_args="$cmake_args -DCMAKE_VERBOSE_MAKEFILE=ON -k"
        make_args="VERBOSE=1 $make_args"
        verbose=1
        shift;
        ;;
      -V | --Verbose)
        echo "CMake build process verbose"
        verbose=1
        shift;
        ;;
      *)
        echo "Unknown option $1"
        help
        return 1
        ;;
    esac
  done


  if [ ! -d /usr/local/etc/oai ]; then
    $SUDO mkdir -m 777 -p /usr/local/etc/oai
  fi

  set_openair_env

  local dlog=$OPENAIRCN_DIR/build/log
  local dext=$OPENAIRCN_DIR/build/ext

  mkdir -m 777 -p $dlog
  mkdir -m 777 -p $dext

  if [ $var_check_install_min_deps -gt 0 ];then
    check_install_upf_min_deps  $force $debug
    if [[ $? -ne 0 ]]; then
        echo_error "Error: UPF minimal deps installation failed"
        return 1
    else
        # Done now after
        disable_ipv6
        echo_success "UPF minimal deps installation successful"
        echo_warning "UPF not compiled, to compile it, re-run build_upf without -i option"
        return 0
    fi
  fi
  if [ $var_check_install_deps -gt 0 ];then
    check_install_upf_deps  $force $debug
    if [[ $? -ne 0 ]]; then
        echo_error "Error: UPF deps installation failed"
        return 1
    else
        # Done now after
        disable_ipv6
        echo_success "UPF deps installation successful"
        echo_warning "UPF not compiled, to compile it, re-run build_upf without -I option"
        return 0
    fi
  fi

  # Taking care of the case we build from dockerfile within openair-epc-fed repository
  if [ -f $OPENAIRCN_DIR/.git ] && [ $IS_CONTAINER -ne 0 ]; then
    pushd $OPENAIRCN_DIR > /dev/null
    rm -f .git
    git init
    git config --global user.email "dummy@dummy.org"
    git config --global user.name "dummy"
    echo "dummy" > dummy.txt
    git add dummy.txt
    git commit -m "dummy"
    popd > /dev/null
  fi

  cmake_args="$cmake_args  -DBUILD_SHARED_LIBS=OFF"
  ##############################################################################
  # Clean
  ##############################################################################
  cd $OPENAIRCN_DIR/build/upf
  if [ $clean -ne 0 ]; then
    if [[ $verbose -eq 1 ]]; then
      echo "Cleaning UPF: generated configuration files, obj files, executable"
    fi
    rm -Rf $OPENAIRCN_DIR/build/upf/build  2>&1
    mkdir -m 777 -p -v build
  fi

  ##############################################################################
  # Compile S/P-GW
  ##############################################################################

  if [ -d /usr/include/aarch64-linux-gnu ]; then
    echo "Linking include dirs for aarch64"
    $SUDO ln -s /usr/include/aarch64-linux-gnu/asm /usr/include/asm
    $SUDO ln -s /usr/include/aarch64-linux-gnu/bits /usr/include/bits
    $SUDO ln -s /usr/include/aarch64-linux-gnu/gnu /usr/include/gnu
    $SUDO cp -s /usr/include/aarch64-linux-gnu/sys/* /usr/include/sys/.
  fi
  if [ -d /usr/include/x86_64-linux-gnu ]; then
    $SUDO ln -s /usr/include/x86_64-linux-gnu/asm /usr/include/asm
    $SUDO ln -s /usr/include/x86_64-linux-gnu/bits /usr/include/bits
    $SUDO ln -s /usr/include/x86_64-linux-gnu/gnu /usr/include/gnu
    $SUDO cp -s /usr/include/x86_64-linux-gnu/sys/* /usr/include/sys/.
  fi

  cd $OPENAIRCN_DIR/build/upf
  if [ ! -d ./build ]; then
    mkdir -m 777 -p -v build
  fi

  cd ./build
  OS_BASE=$(grep "^ID_LIKE=" /etc/os-release | sed "s/ID_LIKE=//" | sed "s/\"//g")
  echo "OS_BASE = ${OS_BASE}"
  $CMAKE $cmake_args ..
  ret=$?;[[ $ret -ne 0 ]] && return $ret

  compilations upf upf $OPENAIRCN_DIR/build/upf/build/upf $verbose
  ret=$?;[[ $ret -ne 0 ]] && return $ret

  # For daemon should not be group writable
  $SUDO chmod 755 $OPENAIRCN_DIR/build/upf/build/upf
  $SUDO cp -upv $OPENAIRCN_DIR/build/upf/build/upf $INSTALL_DIR && $SUDO chmod 755 $INSTALL_DIR/upf && echo_success "upf installed"
  return 0
}


main "$@"
