#!/usr/bin/env bash
set -euo pipefail

# This script wraps npm so to run `mise reshim` after global installs and uninstalls
# Any other cases are passed-through to npm

this_dir=$(dirname "${BASH_SOURCE[0]}")
plugin_name=$(basename "$(dirname "$this_dir")")

this_dir=$(cd "$this_dir" && pwd -P) # Normalizes the directory

plugin_dir="${this_dir}/.."

should_reshim() {
  if [ "${MISE_SKIP_RESHIM:-}" ]; then
    return 1
  fi

  local is_global='' cmd='' cmd_needs_reshim=''
  local additional_bare_cmds=()

  for arg; do
    case "$arg" in
    -g | --global)
      is_global=true
      ;;

    -*) ;; # Skip other options

    *)
      if ! [ "$cmd" ]; then
        cmd="$arg"
      else
        additional_bare_cmds+=("$arg")
      fi
      ;;
    esac
  done

  case "$cmd" in
  # npm install aliases
  install | i | in | ins | inst | insta | instal | isnt | isnta | isntal | add)
    cmd_needs_reshim=true
    ;;

  # npm uninstall aliases
  uninstall | un | unlink | remove | rm | r)
    cmd_needs_reshim=true
    ;;

  link | ln)
    # Bare link installs a global package
    if ! [ "${additional_bare_cmds[0]-}" ]; then
      is_global=1
      cmd_needs_reshim=true
    fi

    # Links to directories also install a global package
    if [[ "${additional_bare_cmds[0]-}" =~ [./].* && -d "${additional_bare_cmds[0]-}" ]]; then
      is_global=1
      cmd_needs_reshim=true
    fi
    ;;
  esac

  # Implicit return
  [ "$is_global" ] && [ "$cmd_needs_reshim" ]
}

wrap_npm_if_reshim_is_needed() {
  local npm_cli="$plugin_dir/lib/node_modules/npm/bin/npm-cli.js"
  local node_bin="$plugin_dir/bin/node"
  if should_reshim "$@"; then
    "$node_bin" "$npm_cli" "$@"
    printf "Reshimming mise %s...\n" "$plugin_name" >&2
    mise reshim
  else
    exec "$node_bin" "$npm_cli" "$@"
  fi
}

wrap_npm_if_reshim_is_needed "$@"
