#!/usr/bin/env bash

set -e            # fail fast
set -o pipefail   # don't ignore exit codes when piping output
# set -x          # enable debugging

# Configure directories
build_dir=$1
cache_dir=$2
env_dir=$3

bp_dir=$(cd $(dirname $0); cd ..; pwd)

# Load some convenience functions like status() and indent()
source $bp_dir/bin/common.sh

# Output npm debug info on error
trap cat_npm_debug_log ERR

# Get node version
node_version=$(node --version)
status "Using Node.js $node_version"

# Run subsequent node/npm commands from the build path
cd $build_dir

install() {
  (
    # Scope config var availability only to `npm install`
    if [ -d "$env_dir" ]; then
      status "Exporting config vars to environment"
      export_env_dir $env_dir
    fi

    status "Installing npm dependencies"
    # Make npm output to STDOUT instead of its default STDERR
    npm install --loglevel=http --userconfig $build_dir/.npmrc "$@" 2>&1 | indent
  )
}

# If node_modules directory is checked into source control then
# rebuild any native deps. Otherwise, restore from the build cache.
if test -d $build_dir/node_modules; then
  status "Found existing node_modules directory; skipping cache"
  # Attempt to work around npm/npm#5400
  install --ignore-scripts
  status "Rebuilding any native dependencies to work around npm/npm#5400"
  npm rebuild 2>&1 | indent
elif test -d $cache_dir/node/node_modules; then
  status "Restoring node_modules directory from cache"
  cp_keep_links -R $cache_dir/node/node_modules $build_dir/

  status "Pruning cached dependencies not specified in package.json"
  npm prune 2>&1 | indent

  if test -f $cache_dir/node/.heroku/node-version && [ $(cat $cache_dir/node/.heroku/node-version) != "$node_version" ]; then
    status "Node version changed since last build; rebuilding dependencies"
    npm rebuild 2>&1 | indent
  fi

  # Let's hope that npm/npm#5400 only hits us on the first run
  install
else
  # Attempt to work around npm/npm#5400
  install --ignore-scripts
  status "Rebuilding any native dependencies to work around npm/npm#5400"
  npm rebuild 2>&1 | indent
fi

# Persist goodies like node-version in the slug
mkdir -p $build_dir/.heroku

# Save resolved node version in the slug for later reference
echo $node_version > $build_dir/.heroku/node-version

# Purge node-related cached content, being careful not to purge the top-level
# cache, for the sake of heroku-buildpack-multi apps.
rm -rf $cache_dir/node
mkdir -p $cache_dir/node

# If app has a node_modules directory, cache it.
if test -d $build_dir/node_modules; then
  status "Caching node_modules directory for future builds"
  cp_keep_links -R $build_dir/node_modules $cache_dir/node
fi

# Copy goodies to the cache
cp -r $build_dir/.heroku $cache_dir/node

status "Cleaning up node-gyp and npm artifacts"
rm -rf "$build_dir/.node-gyp"
rm -rf "$build_dir/.npm"
