#!/usr/bin/env bash

__rvm_ruby_string_fuzzy_remote_for()
{
  typeset new_ruby_string
  new_ruby_string="$(
    __list_remote_$1_for $( __rvm_system_path_for ${2:-$1} ) |
    __rvm_awk -F/ '{x=$NF; gsub(".tar.*","",x); gsub("jruby-bin","jruby",x); print x}' |
    __rvm_grep "${rvm_ruby_string/rbx/rubinius}" |
    sort | __rvm_tail -n 1
  )"
  rvm_ruby_string="${new_ruby_string:-$rvm_ruby_string}"
}

__rvm_ruby_string_fuzzy_remote()
{
  case "${rvm_ruby_string}" in
    (jruby*)         __rvm_ruby_string_fuzzy_remote_for jruby       ;;
    (rbx*|rubinius*) __rvm_ruby_string_fuzzy_remote_for rbx         ;;
    (*)              __rvm_ruby_string_fuzzy_remote_for ruby rubies ;;
  esac
  true
}

__rvm_ruby_string_fuzzy()
{
  typeset new_ruby_string
  new_ruby_string="$(
    __rvm_list_strings | __rvm_grep "${rvm_ruby_string}" | \sort | __rvm_tail -n 1
  )"
  if [[ -n "${new_ruby_string}" ]]
  then rvm_ruby_string="${new_ruby_string}"
  else return $?
  fi
}

__rvm_ruby_string_parse_()
{
  typeset ruby_string gemset_name expanded_alias_name repo_url branch_name ruby_name

  # Stash the ruby string.
  ruby_string="${rvm_ruby_string:-}"
  gemset_name="${rvm_gemset_name:-}"
  repo_url="${rvm_ruby_repo_url:-}"
  branch_name="${rvm_ruby_repo_branch:-}"
  ruby_name="${rvm_ruby_name:-}"

  __rvm_unset_ruby_variables

  rvm_ruby_repo_url="${repo_url:-}"
  rvm_ruby_repo_branch="${branch_name:-}"
  rvm_ruby_name="$ruby_name"

  strings=()
  __rvm_custom_separated_array strings - "${ruby_string}"

  if
    (( ${#strings[@]} == 0 ))
  then
    if
      [[ "${GEM_HOME:-}" == *"${rvm_gems_path}"* ]]
    then
      # Current Ruby
      strings="${GEM_HOME##*\/}"
      strings="${strings/%${rvm_gemset_separator:-"@"}*}"
      rvm_ruby_string="$strings"
      strings=( $(echo ${rvm_ruby_string//-/ }) )
    else
      strings=(system)
      rvm_ruby_string="system"
    fi
  fi

  for string in ${strings[@]}
  do
    case "$string" in
      (head)
        rvm_ruby_patch_level=""
        rvm_ruby_revision=""
        rvm_ruby_tag=""
        export rvm_head_flag=1
        ;;

      (system)
        rvm_ruby_interpreter="system"
        rvm_ruby_patch_level=""
        rvm_ruby_tag=""
        rvm_ruby_revision=""
        rvm_ruby_version=""
        rvm_gemset_name=""
        rvm_head_flag=0
        return 0
        ;;

      (ext|external)
        rvm_ruby_interpreter="ext"
        rvm_ruby_patch_level=""
        rvm_ruby_tag=""
        rvm_ruby_revision=""
        rvm_ruby_version=""
        rvm_head_flag=0

        rvm_ruby_name="${ruby_string:-${rvm_ruby_string}}"
        rvm_ruby_name="${rvm_ruby_name#*-}"
        break
        ;;

      (nightly|weekly|monthly)
        case "${rvm_ruby_interpreter}" in
          (rbx|rubinius) rvm_ruby_patch_level="$string" ;;
          (*)            rvm_ruby_version="$string"     ;;
        esac
        rvm_nightly_flag=1
        ;;

      (nightly*|weekly*|monthly*)
        case "${rvm_ruby_interpreter}" in
          (rbx|rubinius) rvm_ruby_patch_level="$string" ;;
          (*)            rvm_ruby_version="$string"     ;;
        esac
        ;;

      (preview*)
        rvm_ruby_patch_level="$string"
        ;;

      (rc[0-9]*)
        rvm_ruby_patch_level="$string"
        ;;

      (+([0-9]).+([0-9]).[0-9]*)
        rvm_ruby_version="${string}"
        rvm_ruby_revision=""
        rvm_ruby_tag=""
        ;;

      ([0-9][0-9]*)
        case "${rvm_ruby_interpreter:-""}" in
          (ree|kiji)
            rvm_ruby_patch_level="$string"
            rvm_ruby_revision=""
            ;;
          (maglev)
            rvm_ruby_version="$string"
            rvm_ruby_revision=""
            rvm_ruby_patch_level=""
            ;;
          (*)
            rvm_ruby_version="${string}"
            rvm_ruby_revision=""
            rvm_ruby_tag=""
            __check_latest=1
            ;;
        esac
        ;;

      ([0-9]*)
        rvm_ruby_version="${string}"
        rvm_ruby_revision=""
        rvm_ruby_tag=""
        __check_latest=1
        ;;

      (p[0-9]*)
        rvm_ruby_patch_level="$string"
        ;;

      (r[0-9]*)
        rvm_ruby_patch_level=""
        rvm_ruby_revision="$string"
        ;;

      (s[0-9a-zA-Z]*)
        rvm_ruby_revision=""
        rvm_ruby_sha="${string#s}"
        ;;

      (tv[0-9]*|t[0-9]*)
        rvm_ruby_patch_level="" ; rvm_ruby_revision=""
        rvm_ruby_tag="$string"
        ;;

      (m[0-9]*)
        rvm_ruby_mode="$string"
        ;;

      (u[0-9a-zA-Z]*)
        rvm_ruby_patch_level="" ; rvm_ruby_revision="" ; rvm_ruby_tag="" ; rvm_ruby_patch=""
        rvm_ruby_user_tag="$string"
        ;;

      (a[0-9][0-9]*)
        rvm_ruby_bits="$string" # Architecture
        ;;

      (b[0-9]*)
        rvm_ruby_repo_branch="${string}"
        rvm_head_flag=1
        ;;

      (rubinius)
        rvm_ruby_interpreter="rbx"
        ;;

      (opal|ruby|rbx|jruby|macruby|ree|kiji|maglev|ironruby|goruby|mruby|tcs|jamesgolick|topaz)
        rvm_ruby_interpreter="$string"
        ;;

      ([a-zA-Z]*([0-9a-zA-Z]|_))
        rvm_ruby_name="$string"
        ;;

      (*)
        rvm_ruby_string="${ruby_string:-}"
        __check_latest=1
        return 0
        ;;
    esac
  done
  if
    [[ -z "${rvm_ruby_interpreter}" && -n "${rvm_ruby_version}" ]]
  then
    case "${rvm_ruby_version}" in
      (1.[5-7]*)    rvm_ruby_interpreter=jruby ;;
      (1.[8-9]*|2*) rvm_ruby_interpreter=ruby  ;;
    esac
  fi
  true # OSX --trace FIX
}

__rvm_ruby_string_latest()
{
  typeset check_ruby_string new_ruby_string
  check_ruby_string=""
  if [[ -n "${rvm_ruby_interpreter}" ]]
  then check_ruby_string+="${rvm_ruby_interpreter}-"
  fi
  if [[ -n "${rvm_ruby_version}" ]]
  then check_ruby_string+="${rvm_ruby_version//\./\.}.*"
  fi
  if [[ -n "${rvm_ruby_patch_level}" ]]
  then check_ruby_string+="${rvm_ruby_patch_level//\./\.}.*"
  fi
  if [[ -z "${check_ruby_string}" ]]
  then check_ruby_string="$orig_rvm_ruby_string"
  fi
  new_ruby_string="$(
    \cat "$rvm_path/config/known_strings" |
    __rvm_grep "${check_ruby_string}" |
    sort | __rvm_tail -n 1
  )"
  if
    [[ -n "${new_ruby_string}" ]]
  then
    rvm_ruby_string="${new_ruby_string}"
  else
    rvm_error "Unknown ruby string (do not know how to handle): $orig_rvm_ruby_string."
    return 1
  fi
}

__rvm_ruby_string_parse()
{
  typeset orig_rvm_ruby_string __check_latest
  orig_rvm_ruby_string="${rvm_ruby_string}"
  __check_latest=0
  if
    (( ${rvm_fuzzy_flag:-0} == 1 )) &&
    [[ ! -d "${rvm_rubies_path}/${rvm_ruby_string}" ]]
  then
    if
      (( ${rvm_remote_flag:-0} == 1 ))
    then
      __rvm_ruby_string_fuzzy        ||
      __rvm_ruby_string_fuzzy_remote ||
      return $?
    else
      __rvm_ruby_string_fuzzy || true
    fi
  fi
  __rvm_ruby_string_parse_ || return $?
  if
    (( __check_latest ))
  then
    __rvm_ruby_string_latest &&
    __rvm_ruby_string_parse_ ||
    return $?
  fi
  if
    [[ -z "${rvm_ruby_interpreter}" ]]
  then
    rvm_error "Unknown ruby interpreter version (do not know how to handle): $orig_rvm_ruby_string."
    return 1
  fi
}
