#!/bin/bash
# Copyright (C) 2022 The Android Open Source Project
#
# Licensed 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.

# Utils library script for the tradefed harnesses. Its functions can be used
# once the script is sourced, for example by adding
#   source ${ANDROID_BUILD_TOP}/platform_testing/scripts/test-utils-script
# in a script.
#
# It provides a collection of functions which can be called from the other
# scripts.

checkFile() {
    if [ ! -f "$1" ]; then
        echo "Unable to locate $1"
        exit
    fi;
}

checkPath() {
    if ! type -P $1 &> /dev/null; then
        echo "Unable to find $1 in path."
        exit
    fi;
}

# readlink does not work on MacOS so rely on our own realpath
realpath() {
    [[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}"
}

checkJavaVersion() {
  # check java version
  local java_cmd=$1
  local java_version_string=$(${java_cmd} -version 2>&1 | grep -E "\<version\>")
  local JAVA_VERSION=$(echo "$java_version_string" | grep -E 'version [ "](1\.8|9|11|17|21).*[ "]')
  if [ "${JAVA_VERSION}" == "" ]; then
      >&2 echo "Wrong java version. Allowed versions: 1.8, 9, 11, 17, 21. Found $java_version_string"
      >&2 echo "Java command: $java_cmd"
      >&2 echo "PATH value:"
      >&2 echo "$PATH"
      if [ "${IGNORE_JAVA_VERSION_ERROR}" == "y" ]; then
          >&2 echo "Ignoring the wrong java version error as \$IGNORE_JAVA_VERSION_ERROR is set to 'y'"
      else
          >&2 echo "If you want to ignore this error, set \$IGNORE_JAVA_VERSION_ERROR to 'y'"
          exit 8
      fi
  fi
}

getAddOpensFlag() {
  local java_cmd=$1
  local java_version_string=$(${java_cmd} -version 2>&1 | grep -E "\<version\>")
  # java versions below 1.8 are not supported, java versions above 1.8 need add-opens
  local JAVA_VERSION=$(echo "$java_version_string" | grep -E 'version [ "]1\.8.*[ "]')
  if [ "${JAVA_VERSION}" == "" ]; then
      echo "--add-opens=java.base/java.nio=ALL-UNNAMED --add-opens=java.base/sun.reflect.annotation=ALL-UNNAMED"
  fi
}

getRemoteDbgFlag() {
  # check debug flag and set up remote debugging
  # depends on $TF_DEBUG and $TF_DEBUG_PORT
  if [ -n "${TF_DEBUG}" ]; then
    if [ -z "${TF_DEBUG_PORT}" ]; then
      TF_DEBUG_PORT=10088
    fi
    echo "-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=${TF_DEBUG_PORT}"
  fi
}

loadSharedLibraries() {
  # load any shared libraries for host-side executables
  local HOST=$1
  local LIB_DIR=$2
  if [ "$HOST" == "Linux" ]; then
    LD_LIBRARY_PATH=${LIB_DIR}:${LIB_DIR}64:${LD_LIBRARY_PATH}
    export LD_LIBRARY_PATH
  elif [ "$HOST" == "Darwin" ]; then
    DYLD_LIBRARY_PATH=${LIB_DIR}:${LIB_DIR}64:${DYLD_LIBRARY_PATH}
    export DYLD_LIBRARY_PATH
  fi
}
