#!/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.

set -o pipefail

# Bundle a native library if requested. Exit 1 in case error happens.
# Usage: bundle_native_lib bundleoption liboption libpattern libdir
function bundle_native_lib()
{
  declare bundleoption="$1"
  declare liboption="$2"
  declare libpattern="$3"
  declare libdir="$4"


  echo "Checking to bundle with:"
  echo "bundleoption=${bundleoption}, liboption=${liboption}, pattern=${libpattern} libdir=${libdir}"

  if [[ "${bundleoption}" != "true" ]]; then
    return
  fi

  if [[ -z "${libdir}" ]] || [[ ! -d "${libdir}" ]]; then
    echo "The required option ${liboption} isn't given or invalid. Bundling the lib failed"
    exit 1
  fi

  cd "${libdir}"  || exit 1
  ${TAR} ./*"${libpattern}"* | (cd "${TARGET_DIR}"/ || exit 1; ${UNTAR})
  if [[ $? -ne 0 ]]; then
    echo "Bundling library with ${liboption} failed "
    exit 1
  fi
}

function bundle_native_bin
{
  declare bundleoption="$1"
  declare libbundle="$2"
  declare binoption="$3"
  declare binpattern="$4"
  declare libdir="$5"

  echo "Checking to bundle with:"
  echo "bundleoption=${bundleoption}, libbundle=${libbundle}, binoption=${binoption}, libdir=${libdir}, binpattern=${binpattern}"


  if [[ "${bundleoption}" != "true" ]]; then
    return
  fi

  if [[ "${libbundle}" != "true" ]]; then
    return
  fi

  if [[ -z "${libdir}" ]] || [[ ! -d "${libdir}" ]]; then
    echo "The required option ${liboption} isn't given or invalid. Bundling the lib failed"
    exit 1
  fi

  cd "${libdir}" || exit 1
  ${TAR} ./*"${libpattern}"* | (cd "${TARGET_BIN_DIR}"/  || exit 1 ; ${UNTAR})
  if [[ $? -ne 0 ]]; then
    echo "Bundling bin files for ${binoption} failed"
    exit 1
  fi
}

for i in "$@"; do
  case "${i}" in
    --version=*)
      VERSION=${i#*=}
    ;;
    --artifactid=*)
      ARTIFACTID=${i#*=}
    ;;
    --builddir=*)
      BUILD_DIR=${i#*=}
    ;;
    --isallib=*)
      ISALLIB=${i#*=}
    ;;
    --isalbundle=*)
      ISALBUNDLE=${i#*=}
    ;;
    --opensslbinbundle=*)
      OPENSSLBINBUNDLE=${i#*=}
    ;;
    --openssllib=*)
      OPENSSLLIB=${i#*=}
    ;;
    --openssllibbundle=*)
      OPENSSLLIBBUNDLE=${i#*=}
    ;;
    --snappybinbundle=*)
      SNAPPYBINBUNDLE=${i#*=}
    ;;
    --snappylib=*)
      SNAPPYLIB=${i#*=}
    ;;
    --snappylibbundle=*)
      SNAPPYLIBBUNDLE=${i#*=}
    ;;
    --zstdbinbundle=*)
      ZSTDBINBUNDLE=${i#*=}
    ;;
     --zstdlib=*)
      ZSTDLIB=${i#*=}
    ;;
    --zstdlibbundle=*)
      ZSTDLIBBUNDLE=${i#*=}
    ;;

  esac
done

TAR='tar cf -'
UNTAR='tar xfBp -'
LIB_DIR="${BUILD_DIR}/native/target/usr/local/lib"
BIN_DIR="${BUILD_DIR}/bin"
TARGET_DIR="${BUILD_DIR}/${ARTIFACTID}-${VERSION}/lib/native"
TARGET_BIN_DIR="${BUILD_DIR}/${ARTIFACTID}-${VERSION}/bin"


# Most systems

if [[ -d "${LIB_DIR}" ]]; then
  mkdir -p "${TARGET_DIR}"
  cd "${LIB_DIR}" || exit 1
  ${TAR} lib* | (cd "${TARGET_DIR}"/ || exit 1; ${UNTAR})
  if [[ $? -ne 0 ]]; then
    echo "Bundling lib files failed"
    exit 1
  fi

  bundle_native_lib "${SNAPPYLIBBUNDLE}" "snappy.lib" "snappy" "${SNAPPYLIB}"

  bundle_native_lib "${ZSTDLIBBUNDLE}" "zstd.lib" "zstd" "${ZSTDLIB}"

  bundle_native_lib "${OPENSSLLIBBUNDLE}" "openssl.lib" "crypto" "${OPENSSLLIB}"

  bundle_native_lib "${ISALBUNDLE}" "isal.lib" "isa" "${ISALLIB}"
fi

# Windows

# Windows doesn't have a LIB_DIR, everything goes into bin

if [[ -d "${BIN_DIR}" ]] ; then
  mkdir -p "${TARGET_BIN_DIR}"
  cd "${BIN_DIR}"  || exit 1
  ${TAR} ./* | (cd "${TARGET_BIN_DIR}"/ || exit 1; ${UNTAR})
  if [[ $? -ne 0 ]]; then
    echo "Bundling bin files failed"
    exit 1
  fi

  bundle_native_bin "${SNAPPYBINBUNDLE}" "${SNAPPYLIBBUNDLE}" "snappy.lib" "snappy" "${SNAPPYLIB}"

  bundle_native_bin "${ZSTDBINBUNDLE}" "${ZSTDLIBBUNDLE}" "zstd.lib" "zstd" "${ZSTDLIB}"

  bundle_native_bin "${OPENSSLBINBUNDLE}" "${OPENSSLLIBBUNDLE}" "openssl.lib" "crypto" "${OPENSSLLIB}"

fi
