#!/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#*=}
    ;;
    --pmdklib=*)
      PMDKLIB=${i#*=}
    ;;
    --pmdkbundle=*)
      PMDKBUNDLE=${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}"

  bundle_native_lib "${PMDKBUNDLE}" "pmdk.lib" "pmdk" "${PMDKLIB}"
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
