#!/bin/bash
#
# Summary: Create build definitions from nodejs.org
#
# Usage: nodenv update-version-defs [-f] [-d <dir>] [-e <pattern> ] [-n]
#        [--nodejs] [--nodejs-pre] [--nodejs-nightly]
#        [--chakracore] [--chakracore-pre] [--chakracore-nightly]
#        [--graal]
#
# Scrapes nodejs.org to create build definitions for node
# versions not yet available to node-build
#
#   -d/--destination   Directory where build definitions will be written
#   -e/--regexp        Only write definitions whose basename patches the pattern.
#                      Useful with -f to force overwrite a subset of definitions.
#   -f/--force         Write build definitions that already exist somewhere in
#                      NODE_BUILD_DEFINITIONS paths; possibly overwriting
#   -n/--dry-run       Print build definitions that would have been written;
#                      without doing so
#
#   --nodejs              Scrape nodejs.org for node definitions;
#   --nodejs-pre          Scrape nodejs.org for node pre-release definitions;
#   --nodejs-nightly      Scrape nodejs.org for node nightly definitions;
#   --chakracore          Scrape nodejs.org for chakracore definitions;
#   --chakracore-pre      Scrape nodejs.org for chakracore pre-release definitions;
#   --chakracore-nightly  Scrape nodejs.org for chakracore nightly definitions;
#   --graal               Scrape github.com for graalvm definitions;
#                         Defaults to --nodejs, if none given
#
# Notes: If this plugin is not installed directly into "$NODENV_ROOT/plugins",
# (ie, homebrew, npm, etc) then 'share/node-build' must be added to the
# colon-separated NODE_BUILD_DEFINITIONS path manually.
#

set -e

resolve_link() {
  $(type -p greadlink readlink | head -1) "$1"
}

abs_dirname() {
  local cwd="$PWD"
  local path="$1"

  while [ -n "$path" ]; do
    cd "${path%/*}" || exit
    local name="${path##*/}"
    path="$(resolve_link "$name" || true)"
  done

  pwd
  cd "$cwd"
}

INSTALL_PREFIX="$(abs_dirname "${BASH_SOURCE[0]}")/.."

# prepend our share dir to defs path; the first path will be the write target
# also insert NODE_BUILD_ROOT, if set
NODE_BUILD_DEFINITIONS="${INSTALL_PREFIX}/share/node-build${NODE_BUILD_ROOT:+:$NODE_BUILD_ROOT}${NODE_BUILD_DEFINITIONS:+:$NODE_BUILD_DEFINITIONS}"

# Add `share/node-build/` directory from each nodenv plugin to the list of
# paths where build definitions are looked up.
shopt -s nullglob
for plugin_path in "$NODENV_ROOT"/plugins/*/share/node-build; do
  NODE_BUILD_DEFINITIONS="${NODE_BUILD_DEFINITIONS%:}:${plugin_path}"
done
export NODE_BUILD_DEFINITIONS
shopt -u nullglob

declare -a SCRAPERS
unset DRY_RUN
unset FORCE
unset PATTERN

# Provide nodenv completions
while [ $# -gt 0 ]; do
  case "$1" in
    --complete )
      echo --destination
      echo --dry-run
      echo --force
      echo --regexp
      echo --nodejs
      echo --nodejs-pre
      echo --nodejs-nightly
      echo --chakracore
      echo --chakracore-pre
      echo --chakracore-nightly
      echo --graal
      exit ;;
    -d | --destination )
      shift
      # overwrite the defs write target
      NODE_BUILD_DEFINITIONS="$(abs_dirname "${1%/}/"):${NODE_BUILD_DEFINITIONS}" ;;
    -n | --dry-run)
      DRY_RUN=true ;;
    -f | --force)
      FORCE=true ;;
    -e | --regexp)
      PATTERN=$2
      shift ;;
    --nodejs | --nodejs-pre | --nodejs-nightly | \
    --chakracore | --chakracore-pre | --chakracore-nightly | \
    --graal )
      SCRAPERS+=("${1#--}") ;;
    * )
      nodenv-help --usage update-version-defs >&2
      exit 1;;
  esac
  shift
done

# change to plugin dir so .node-version will be respected
cd "$INSTALL_PREFIX"

node - <<-JS
require('./')({
  dryRun: ${DRY_RUN:-false},
  overwrite: ${FORCE:-false},
  pattern: RegExp('${PATTERN}'),
  run: [ $(printf '"%s",' "${SCRAPERS[@]:-nodejs}") ],
  definitionPaths: '${NODE_BUILD_DEFINITIONS:-share/node-build}'.split(':')
})
JS
