#!/usr/bin/env bash

BUNDLE_VERSION=22.11.0.4


# OS Check. Put here because here is where we download the precompiled
# bundles that are arch specific.
# Use of : "${ARCH:=$(uname)}" assignment permits users to set their
# architecture manually; this is useful for multi-arch systems whose
# uname executables may sometimes return different architectures
# in
# different contexts.
#   Ex: ARCH=arm64 meteor ARGS...;
UNAME="$(uname)"
if [ "$UNAME" != "Linux" -a "$UNAME" != "Darwin" ] ; then
    echo "Sorry, this OS is not supported."
    exit 1
fi

if [ "$UNAME" = "Darwin" ] ; then
    if [ "arm64" == "$(uname -m)" ]; then
      : "${ARCH:=arm64}"
    else
      if [ "i386" != "$(uname -p)" -o "1" != "$(sysctl -n hw.cpu64bit_capable 2>/dev/null || echo 0)" ] ; then

          # Can't just test uname -m = x86_64, because Snow Leopard can
          # return other values.
          echo "Only 64-bit and arm64 processors are supported at this time."
          exit 1
      fi
      : "${ARCH:=x86_64}"
    fi
elif [ "$UNAME" = "Linux" ] ; then
    : "${ARCH:=$(uname -m)}"
    if [[ "$ARCH" != "x86_64" && "$ARCH" != "aarch64" ]] ; then
        echo "Unsupported architecture: $ARCH"
        echo "Meteor only supports x86_64 and aarch64"
        exit 1
    fi
fi
PLATFORM="${UNAME}_${ARCH}"

# Find the script dir, following symlinks. Note that symlink can be relative or
# absolute. Too bad 'readlink -f' and 'realpath' (the command-line program) are
# not portable.  We don't stress about infinite loops or bad links, because the
# OS has already resolved this symlink chain once in order to actually run the
# shell script.
ORIG_DIR="$(pwd)"
SCRIPT="$0"
while true; do
  # The symlink might be relative, so we have to actually cd to the right place
  # each time in order to resolve it.
  cd "$(dirname "$SCRIPT")"
  if [ ! -L "$(basename "$SCRIPT")" ]; then
    SCRIPT_DIR="$(pwd -P)"
    break
  fi
  SCRIPT="$(readlink "$(basename "$SCRIPT")")"
done
cd "$ORIG_DIR"



function install_dev_bundle {
    set -e
    trap "echo Failed to install dependency kit." EXIT

    TARBALL="dev_bundle_${PLATFORM}_${BUNDLE_VERSION}.tar.gz"
    BUNDLE_TMPDIR="$SCRIPT_DIR/dev_bundle.xxx"

    rm -rf "$BUNDLE_TMPDIR"
    mkdir "$BUNDLE_TMPDIR"

    # duplicated in scripts/windows/download-dev-bundle.ps1:
    DEV_BUNDLE_URL_ROOT="https://d3sqy0vbqsdhku.cloudfront.net/"
    # If you set $USE_TEST_DEV_BUNDLE_SERVER then we will download
    # dev bundles copied by copy-dev-bundle-from-jenkins.sh without --prod.
    # It still only does this if the version number has changed
    # (setting it won't cause it to automatically delete a prod dev bundle).
    if [ -n "$USE_TEST_DEV_BUNDLE_SERVER" ] ; then
        DEV_BUNDLE_URL_ROOT="https://s3.amazonaws.com/com.meteor.static/test/"
    fi

    if [ -f "$SCRIPT_DIR/$TARBALL" ] ; then
        echo "Skipping download and installing kit from $SCRIPT_DIR/$TARBALL" >&2
        tar -xzf "$SCRIPT_DIR/$TARBALL" -C "$BUNDLE_TMPDIR"
    elif [ -n "$SAVE_DEV_BUNDLE_TARBALL" ] ; then
        # URL duplicated in tools/server/target.sh.in
        curl -# "$DEV_BUNDLE_URL_ROOT$TARBALL" >"$SCRIPT_DIR/$TARBALL"
        tar -xzf "$SCRIPT_DIR/$TARBALL" -C "$BUNDLE_TMPDIR"
    else
        curl -# "$DEV_BUNDLE_URL_ROOT$TARBALL" | tar -xzf - -C "$BUNDLE_TMPDIR"
    fi

    test -x "${BUNDLE_TMPDIR}/bin/node" # bomb out if it didn't work, eg no net

    # Delete old dev bundle and rename the new one on top of it.
    rm -rf "$SCRIPT_DIR/dev_bundle"
    mv "$BUNDLE_TMPDIR" "$SCRIPT_DIR/dev_bundle"

    echo "Installed dependency kit v${BUNDLE_VERSION} in dev_bundle." >&2
    echo >&2

    trap - EXIT
    set +e
}


if [ -d "$SCRIPT_DIR/.git" ] || [ -f "$SCRIPT_DIR/.git" ]; then
    # In a checkout.
    if [ ! -d "$SCRIPT_DIR/dev_bundle" ] ; then
        echo "It's the first time you've run Meteor from a git checkout." >&2
        echo "I will download a kit containing all of Meteor's dependencies." >&2
        install_dev_bundle
    elif [ ! -f "$SCRIPT_DIR/dev_bundle/.bundle_version.txt" ] ||
        grep -qvx "$BUNDLE_VERSION" "$SCRIPT_DIR/dev_bundle/.bundle_version.txt" ; then
        echo "Your dependency kit is out of date. I will download the new one." >&2
        install_dev_bundle
    fi

    export BABEL_CACHE_DIR="$SCRIPT_DIR/.babel-cache"
fi

DEV_BUNDLE="$SCRIPT_DIR/dev_bundle"
METEOR="$SCRIPT_DIR/tools/index.js"
PROCESS_REQUIRES="$SCRIPT_DIR/tools/node-process-warnings.js"

# Set the nofile ulimit as high as permitted by the hard-limit/kernel
if [ "$(ulimit -Sn)" != "unlimited" ]; then
    if [ "$(uname -s)" = "Darwin" ]; then
        maxfilesuse="$(sysctl -n kern.maxfilesperproc)"
    else
        maxfilesuse="$(ulimit -Hn)"
    fi

    if [ -n "${maxfilesuse}" ] && [ "${maxfilesuse}" != "unlimited" ]; then
        ulimit -Sn ${maxfilesuse} > /dev/null 2>&1
    fi
fi

# We used to set $NODE_PATH here to include the node_modules from the dev
# bundle, but now we just get them from the symlink at tools/node_modules. This
# is better because node_modules directories found via the ancestor walk from
# the script take precedence over $NODE_PATH; it used to be that users would
# screw up their meteor installs by have a ~/node_modules

# --no-wasm-code-gc is currently necessary as a workaround for
# https://github.com/nodejs/node/issues/29767
exec "$DEV_BUNDLE/bin/node" \
     --max-old-space-size=4096 \
     --no-wasm-code-gc \
     --require="$PROCESS_REQUIRES"\
     ${TOOL_NODE_FLAGS} \
     "$METEOR" "$@"
