#!/usr/bin/env bash

build_dir=$1
cache_dir=$2
bp_dir=$(cd $(dirname $0); cd ..; pwd)
stable_version="0.10.18"

source $bp_dir/bin/common.sh

# Output debug info on exit
# trap cat_npm_debug_log EXIT

# Bootstrap the build process with latest stable version of node
# We'll use it to parse package.json and do semver detection
status "Bootstrapping node v$stable_version"
download_and_install_node $stable_version

# Is a node version specified in package.json?
# https://github.com/trentm/json
requested_version=$(cat $build_dir/package.json | $bp_dir/vendor/json engines.node)

# Give a warning if engines.node is unspecified
if ! test $requested_version; then
  node_version=$stable_version
  echo
  echo "WARNING: No node version specified in package.json, see:" | indent
  echo "https://devcenter.heroku.com/articles/nodejs-support#versions" | indent
  echo
  status "Defaulting to latest stable node, v$stable_version"

else
  # Does the already-downloaded stable version of node satisfy the requested version?
  default_satisfies=$($bp_dir/vendor/semver/bin/semver -v "$stable_version" -r "$requested_version" || echo "")

  if test $default_satisfies; then
    status "Latest stable node v$stable_version satisfies engines.node: $requested_version"
    node_version=$stable_version
  else

    # Fetch all versions of node from nodejs.org/dist and format them into
    # a string that the semver binary will appreciate.
    # e.g. semver -v "0.10.0" -v "0.10.1" -v "0.10.2" -r ">0.8"
    # See https://github.com/isaacs/node-semver/blob/master/bin/semver
    args=""
    for version in $(query_all_versions); do args="${args} -v \"${version}\""; done
    args="${args} -r \"${requested_version}\""

    # Find all versions that satisfy.
    satisfying_versions=$(eval $bp_dir/vendor/semver/bin/semver ${args} || echo "")

    # Use the latest one.
    node_version=$(echo "$satisfying_versions" | tail -n 1)

    if test $node_version; then
      status "Downloading and installing node v$version"
      download_and_install_node $node_version
    else
      error "node ${requested_version} not found among available versions on nodejs.org/dist"
    fi
  fi
fi

# Configure cache directories
cache_store_dir="$cache_dir/node_modules/$node_version"
cache_target_dir="$build_dir/node_modules"

cd $build_dir

# Restore node_modules from cache if package.json unchanged.
if test -d $cache_store_dir && diff $cache_store_dir/package.json $build_dir/package.json >/dev/null; then
  status "package.json unchanged; restoring node_modules from cache"
  if test -d $cache_target_dir; then
    cp -r $cache_store_dir/* $cache_target_dir/
  else
    cp -r $cache_store_dir $cache_target_dir
  fi
else
  # Install dependencies anew
  status "Installing dependencies"
  npm install --production | indent
  status "Rebuilding dependencies"
  npm rebuild | indent
fi

# Cache node_modules for future builds
if test -d $cache_target_dir; then
  status "Caching node_modules for future builds"
  rm -rf $cache_store_dir
  mkdir -p $(dirname $cache_store_dir)
  cp -r $cache_target_dir $cache_store_dir
fi

# Update the PATH
status "Building runtime environment"
mkdir -p $build_dir/.profile.d
echo "export PATH=\"\$HOME/vendor/node/bin:$HOME/bin:\$HOME/node_modules/.bin:\$PATH\"" > $build_dir/.profile.d/nodejs.sh
