#!/usr/bin/env bash

#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF 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.
#

SELF=$(cd $(dirname $0) && pwd)
. "$SELF/util.sh"

if [ -z "${JAVA_HOME}" -a "$(command -v javac)" ]; then
  if [ "$(uname -s)" = "Darwin" ]; then
    # For some versions of macOS, "/usr/bin/javac" is a real file instead of a symbolic link,
    # so the JAVA_HOME may be set to path "/usr" improperly.
    # The following command is an appropriate way of setting JAVA_HOME on macOS.
    export JAVA_HOME="$(/usr/libexec/java_home)"
  else
    export JAVA_HOME="$(dirname $(dirname $(realpath $(command -v javac))))"
  fi
fi

# Determine the current working directory
_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
# Preserve the calling directory
_CALLING_DIR="$(pwd)"
# Options used during compilation
_COMPILE_JVM_OPTS="-Xss128m -Xmx4g -XX:ReservedCodeCacheSize=128m"

# Installs any application tarball given a URL, the expected tarball name,
# and, optionally, a checkable binary path to determine if the binary has
# already been installed. Arguments:
# 1 - Mirror host
# 2 - URL path on host
# 3 - URL query string
# 4 - checksum suffix
# 5 - Tarball Name
# 6 - Checkable Binary
install_app() {
  local mirror_host="$1"
  local url_path="$2"
  local url_query="$3"
  local checksum_suffix="$4"
  local local_tarball="${_DIR}/$5"
  local binary="${_DIR}/$6"
  local remote_tarball="${mirror_host}/${url_path}${url_query}"
  local local_checksum="${local_tarball}.${checksum_suffix}"
  local remote_checksum="https://archive.apache.org/dist/${url_path}.${checksum_suffix}"

  local curl_opts="--silent --show-error -L"
  local wget_opts="--no-verbose"

  if [ ! -f "$binary" ]; then
    # check if we already have the tarball
    # check if we have curl installed
    # download application
    if [ ! -f "${local_tarball}" -a "$(command -v curl)" ]; then
      echo "exec: curl ${curl_opts} ${remote_tarball}" 1>&2
      curl ${curl_opts} "${remote_tarball}" > "${local_tarball}"
      if [ ! -z "${checksum_suffix}" ]; then
        echo "exec: curl ${curl_opts} ${remote_checksum}" 1>&2
        curl ${curl_opts} "${remote_checksum}" > "${local_checksum}"
      fi
    fi
    # if the file still doesn't exist, lets try `wget` and cross our fingers
    if [ ! -f "${local_tarball}" -a "$(command -v wget)" ]; then
      echo "exec: wget ${wget_opts} ${remote_tarball}" 1>&2
      wget ${wget_opts} -O "${local_tarball}" "${remote_tarball}"
      if [ ! -z "${checksum_suffix}" ]; then
        echo "exec: wget ${wget_opts} ${remote_checksum}" 1>&2
        wget ${wget_opts} -O "${local_checksum}" "${remote_checksum}"
      fi
    fi
    # if both were unsuccessful, exit
    if [ ! -f "${local_tarball}" ]; then
      echo -n "ERROR: Cannot download ${remote_tarball} with cURL or wget; please install manually and try again."
      exit 2
    fi
    # Checksum may not have been specified; don't check if doesn't exist
    if [ "$(command -v shasum)" ]; then
      if [ -f "${local_checksum}" ]; then
        echo "  ${local_tarball}" >> ${local_checksum} # two spaces + file are important!
        # Assuming SHA512 here for now
        echo "Verifying checksum from ${local_checksum}" 1>&2
        if ! shasum -a 512 -c "${local_checksum}" > /dev/null ; then
          echo "Bad checksum from ${remote_checksum}"
          exit 2
        fi
      fi
    else
      echo "Skipping checksum because shasum is not installed." 1>&2
    fi

    cd "${_DIR}" && tar -xzf "${local_tarball}"
    rm -rf "${local_tarball}"
    rm -f "${local_checksum}"
  fi
}

# See simple version normalization: http://stackoverflow.com/questions/16989598/bash-comparing-version-numbers
function version { echo "$@" | awk -F. '{ printf("%03d%03d%03d\n", $1,$2,$3); }'; }

# Determine the Maven version from the root pom.xml file and
# install maven under the build/ folder if needed.
install_mvn() {
  local MVN_VERSION=`grep "<maven.version>" "${_DIR}/../pom.xml" | head -n1 | awk -F '[<>]' '{print $3}'`
  MVN_BIN="$(command -v mvn)"
  if [ "$MVN_BIN" ]; then
    local MVN_DETECTED_VERSION="$(mvn --version | head -n1 | awk '{print $3}')"
  fi
  if [ $(version $MVN_DETECTED_VERSION) -ne $(version $MVN_VERSION) ]; then
    local MVN_TARBALL="apache-maven-${MVN_VERSION}-bin.tar.gz"
    local FILE_PATH="maven/maven-3/${MVN_VERSION}/binaries/${MVN_TARBALL}"
    local APACHE_MIRROR=${APACHE_MIRROR:-'https://www.apache.org/dyn/closer.lua'}
    local MIRROR_URL_QUERY="?action=download"

    if [ $(command -v curl) ]; then
      if ! curl -L --output /dev/null --silent --head --fail "${APACHE_MIRROR}/${FILE_PATH}${MIRROR_URL_QUERY}" ; then
        # Fall back to archive.apache.org for older Maven
        echo "Falling back to archive.apache.org to download Maven"
        APACHE_MIRROR="https://archive.apache.org/dist"
        MIRROR_URL_QUERY=""
      fi
    fi

    install_app \
      "${APACHE_MIRROR}" \
      "${FILE_PATH}" \
      "${MIRROR_URL_QUERY}" \
      "sha512" \
      "${MVN_TARBALL}" \
      "apache-maven-${MVN_VERSION}/bin/mvn"

    MVN_BIN="${_DIR}/apache-maven-${MVN_VERSION}/bin/mvn"
  fi
}

install_mvn

# Reset the current working directory
cd "${_CALLING_DIR}"

# Set any `mvn` options if not already present
export MAVEN_OPTS=${MAVEN_OPTS:-"$_COMPILE_JVM_OPTS"}

echo "Using \`mvn\` from path: $MVN_BIN" 1>&2

if [ ! -z "${SPARK_LOCAL_HOSTNAME}" ]; then
  echo "Using SPARK_LOCAL_HOSTNAME=$SPARK_LOCAL_HOSTNAME" 1>&2
fi
if [ ! -z "${SPARK_LOCAL_IP}" ]; then
  echo "Using SPARK_LOCAL_IP=$SPARK_LOCAL_IP" 1>&2
fi

# call the `mvn` command as usual
# SPARK-25854
"${MVN_BIN}" "$@"
MVN_RETCODE=$?

exit $MVN_RETCODE
