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


# generate code
if [ "$ARROW_R_DEV" == "TRUE" ]; then
  echo "*** Generating code with data-raw/codegen.R"
  "${R_HOME}/bin${R_ARCH_BIN}/Rscript.exe" data-raw/codegen.R
fi

OPENSSL_LIBS="-lcrypto -lcrypt32"
MIMALLOC_LIBS="-lbcrypt -lpsapi"
BROTLI_LIBS="-lbrotlienc -lbrotlidec -lbrotlicommon" # Common goes last since dec and enc depend on it
AWS_LIBS="-laws-cpp-sdk-config -laws-cpp-sdk-transfer -laws-cpp-sdk-identity-management \
          -laws-cpp-sdk-cognito-identity -laws-cpp-sdk-sts -laws-cpp-sdk-s3 \
          -laws-cpp-sdk-core -laws-c-event-stream -laws-checksums -laws-c-common \
          -lUserenv -lversion -lws2_32 -lBcrypt -lWininet -lwinhttp"
# pkg-config --libs libcurl
GCS_LIBS="-lcurl -lnormaliz -lssh2 -lgdi32 -lssl -lcrypto -lcrypt32 -lwldap32 \
          -lz -lws2_32 -lnghttp2 -ldbghelp"

function configure_release() {
  VERSION=$(grep ^Version DESCRIPTION | sed s/Version:\ //)
  # Try to find/download a C++ Arrow binary,
  # including possibly a local .zip file if RWINLIB_LOCAL is set
  "${R_HOME}/bin${R_ARCH_BIN}/Rscript.exe" "tools/winlibs.R" $VERSION $RWINLIB_LOCAL
  # If binary not found, script exits nonzero
  if [ $? -ne 0 ]; then
    echo "Arrow C++ library was not found"
  fi

  # Set the right flags to point to and enable arrow/parquet
  if [ -d "windows/arrow-$VERSION" ]; then
    RWINLIB="../windows/arrow-$VERSION"
  else
    # It's possible that the version of the libarrow binary is not identical to the
    # R version, e.g. if the R build is a patch release, so find what the dir is
    # actually called. If there is more than one version present, use the one
    # with the highest version:
    RWINLIB="../windows/$(ls windows/ | grep ^arrow- | tail -n 1)"
  fi

  # NOTE: If you make changes to the libraries below, you should also change
  # ci/scripts/r_windows_build.sh and ci/scripts/PKGBUILD
  PKG_CFLAGS="-I${RWINLIB}/include -DARROW_STATIC -DPARQUET_STATIC -DARROW_DS_STATIC \
              -DARROW_ACERO_STATIC -DARROW_R_WITH_PARQUET -DARROW_R_WITH_ACERO \
              -DARROW_R_WITH_DATASET -DARROW_R_WITH_JSON"
  PKG_LIBS="-L${RWINLIB}/lib"'$(subst gcc,,$(COMPILED_BY))$(R_ARCH) '
  PKG_LIBS="$PKG_LIBS -L${RWINLIB}/lib"'$(R_ARCH)$(CRT) '
  PKG_LIBS="$PKG_LIBS -larrow_dataset -larrow_acero -lparquet -larrow -larrow_bundled_dependencies \
            -lutf8proc -lthrift -lsnappy -lz -lzstd -llz4 -lbz2 ${BROTLI_LIBS} -lole32 \
            ${MIMALLOC_LIBS} ${OPENSSL_LIBS}"

  # S3, GCS, and re2 support only for Rtools40 (i.e. R >= 4.0)
  "${R_HOME}/bin${R_ARCH_BIN}/Rscript.exe" -e 'R.version$major >= 4' | grep TRUE >/dev/null 2>&1
  if [ $? -eq 0 ]; then
    PKG_CFLAGS="${PKG_CFLAGS} -DARROW_R_WITH_S3 -DARROW_R_WITH_GCS"
    PKG_LIBS="${PKG_LIBS} -lre2 ${AWS_LIBS} ${GCS_LIBS}"
  else
    # It seems that order matters
    PKG_LIBS="${PKG_LIBS} -lws2_32"
  fi
}

# Returns 1 if CMAKE options is set "ON", otherwise 0
function cmake_option() {
  ARROW_OPTS_CMAKE="$ARROW_HOME/lib/cmake/Arrow/ArrowOptions.cmake"
  grep -cm1 "set($1 \"ON\")" $ARROW_OPTS_CMAKE
}

function configure_dev() {
  echo "*** Using locally built Arrow at $ARROW_HOME"
  RWINLIB=$(cygpath $ARROW_HOME)

  export PKG_CONFIG_PATH=$(cygpath $ARROW_HOME)/lib/pkgconfig:$(cygpath $MSYSTEM_PREFIX)/lib
  PKG_CONFIG_PACKAGES="arrow"

  PKG_CFLAGS=""

  if [ $(cmake_option ARROW_PARQUET) -eq 1 ]; then
    PKG_CFLAGS="$PKG_CFLAGS -DARROW_R_WITH_PARQUET"
    PKG_CONFIG_PACKAGES="$PKG_CONFIG_PACKAGES parquet"
  fi

  if [ $(cmake_option ARROW_ACERO) -eq 1 ]; then
    PKG_CFLAGS="$PKG_CFLAGS -DARROW_R_WITH_ACERO"
    PKG_CONFIG_PACKAGES="$PKG_CONFIG_PACKAGES arrow-acero"
  fi

  if [ $(cmake_option ARROW_DATASET) -eq 1 ]; then
    PKG_CFLAGS="$PKG_CFLAGS -DARROW_R_WITH_DATASET"
    PKG_CONFIG_PACKAGES="$PKG_CONFIG_PACKAGES arrow-dataset"
  fi

  if [ $(cmake_option ARROW_S3) -eq 1 ]; then
    PKG_CFLAGS="$PKG_CFLAGS -DARROW_R_WITH_S3"
  fi

  if [ $(cmake_option ARROW_GCS) -eq 1 ]; then
    PKG_CFLAGS="$PKG_CFLAGS -DARROW_R_WITH_GCS"
  fi

  if [ $(cmake_option ARROW_JSON) -eq 1 ]; then
    PKG_CFLAGS="$PKG_CFLAGS -DARROW_R_WITH_JSON"
  fi

  if [ $(cmake_option ARROW_SUBSTRAIT) -eq 1 ]; then
    PKG_CFLAGS="$PKG_CFLAGS -DARROW_R_WITH_SUBSTRAIT"
    PKG_CONFIG_PACKAGES="$PKG_CONFIG_PACKAGES arrow-substrait"
  fi

  PKG_CFLAGS="$(pkg-config --cflags $PKG_CONFIG_PACKAGES) $PKG_CFLAGS"
  PKG_LIBS=$(pkg-config --libs $PKG_CONFIG_PACKAGES)
}


if [ ! -z ${ARROW_HOME} ]; then
  # Build Arrow based on local build of libarrow.
  configure_dev
else
  # Build Arrow based on precompiled zip of static libraries.
  configure_release
fi


# Set any user-defined CXXFLAGS
if [ "$ARROW_R_CXXFLAGS" ]; then
  PKG_CFLAGS="$PKG_CFLAGS $ARROW_R_CXXFLAGS"
fi

echo "*** Writing $(pwd)/src/Makevars.win"
sed -e "s|@cflags@|$PKG_CFLAGS|" -e "s|@libs@|$PKG_LIBS|" src/Makevars.in > src/Makevars.win

echo "*** Contents of $(pwd)/src/Makevars.win"
cat src/Makevars.win
echo "*** /End contents"

# Success
exit 0
