#!/usr/bin/env bash

unset GREP_OPTIONS
source "$rvm_path/scripts/base"

usage()
{
  printf "

  Usage:

    rvm upgrade [new ruby] [existing ruby]

  Description:

    Upgrades the latest installed ruby with a given ruby string
    (e.g. ree) to the latest known version or the version specified

"
}

confirm()
{

  local confirmation_response

  printf "$1 (Y/n): "

  read -r confirmation_response

  if [[ -n "$confirmation_response" ]] ; then
    echo $confirmation_response | \grep -qi '^y\|^Y'
  fi
}

die_with_error()
{
  "$rvm_path/scripts/log" "fail" "$1"
  exit "${2:-1}"
}

expand_ruby_name()
{
  "$rvm_path/scripts/tools" strings "$1" \
    | awk -F"${rvm_gemset_separator:-"@"}" '{print $1}'
}

expand_existing_ruby()
{
  local prefix ruby_name

  prefix="$(expand_ruby_name "$1" | awk -F'-' '{print $1"-"$2}')"

  while read -r ruby_name; do

    if [[ "$ruby_name" != "$expanded_destination"* ]]; then
      echo "$ruby_name" ; return 0
    fi

  done < <("$rvm_path/scripts/list" strings | tr ' ' '\n'  \
    | sort -ur | \grep "^$prefix" | \grep -v '-head$' | head -n1)

  return 1
}

upgrade_ruby()
{

  if [[ -z "$source_ruby" ]] ; then
    die_with_error "Unable to find a source ruby. Please manually provide one."
  fi

  expanded_source="$(expand_ruby_name "$source_ruby")"

  if [[ -z "$expanded_source" ]] ; then
    die_with_error "The source ruby was not a valid ruby string."
  fi

  if ! confirm "Are you sure you wish to upgrade from $expanded_source to \
    $expanded_destination?" ; then
    die_with_error "Cancelling upgrade."
  fi

  if [[ ! -d "$rvm_path/rubies/$expanded_destination" ]]; then

    "$rvm_path/scripts/log" "info" \
      "Installing new ruby $expanded_destination"

    "${rvm_bin_path:-"$rvm_path/bin"}/rvm" install "$expanded_destination"

    result="$?"

    if [[ "$result" -gt 0 ]] ; then
      die_with_error "Unable to install ruby $expanded_destination. \
        Please install it manually to continue." "$result"
    fi

  fi

  "$rvm_path/scripts/log" "info" \
    "Migrating gems from $expanded_source to $expanded_destination"

  "$rvm_path/scripts/migrate" "$expanded_source" "$expanded_destination"
  result="$?"

  [[ "$result" -gt 0 ]] && die_with_error "Error migrating gems." "$result"

  "$rvm_path/scripts/log" "info" "Upgrade complete!"
}

args=($*)
destination_ruby="${args[$__array_start]}"
args[$__array_start]=""
args=(${args[@]})

source_ruby="${args[$__array_start]:-"$(expand_existing_ruby "$destination_ruby")"}"
args[$__array_start]=""
args=(${args[@]})

if [[ -z "${source_ruby:-""}" ]] ; then
  usage >&2
  exit 1
fi

if [[ "help" = "$source_ruby" ]] ; then
  usage
  exit 0
fi

expanded_destination="$(expand_ruby_name "$destination_ruby")"

if [[ -z "$source_ruby" ]] ; then
  die_with_error \
    "Source ruby was either not a recognized ruby string or not installed."
fi

if [[ -z "$expanded_destination" ]] ; then
  die_with_error \
    "Destination ruby is not a known ruby string."
fi

upgrade_ruby

exit $?
