#!/usr/bin/env bash

source "$rvm_scripts_path/functions/manage/base_fetch"

# Emits a number of patches to STDOUT, each on a new line
# Expands patchsets etc.
#TODO: Lookup default patches on rvm_ruby_string heirarchy.
__rvm_current_patch_names()
{
  typeset -a expanded_names
  typeset _variable patch_level_separator level name expanded_name
  _variable="${1:-}"
  # Need variable for ${x%...}
  patch_level_separator="%"
  for name in "${rvm_patch_names[@]}" default ${_system_name_lowercase}
  do
    [[ -n "${name:-}" ]] || continue

    if __rvm_string_match "${name}" "*${patch_level_separator}*"
    then level="${name##*${patch_level_separator}}"
    else level=1
    fi

    name="${name%${patch_level_separator}*}"
    __rvm_read_lines expanded_names <( __rvm_expand_patch_name "$name" "$level" )

    rvm_debug "Patch name '$name', expanded_name(s) '${expanded_names[*]}'."

    for expanded_name in "${expanded_names[@]}"
    do
      [[ -z "${expanded_name}" ]] || eval "${_variable}+=( \"\${expanded_name}\" )"
    done
  done
}

__rvm_apply_patches()
{
  typeset patch_name patch_level_separator patch_fuzziness patch_level source_directory full_patch_path _save_dir
  typeset -a patches
  patches=()
  patch_level_separator="%"
  patch_fuzziness="25" # max fuziness that makes sense is 3 (or there are patches with bigger context ?)
  result=0
  source_directory="${1:-"${rvm_src_path}/$rvm_ruby_string"}"
  (( $# == 0 )) || shift

  _save_dir="$PWD"
  __rvm_cd "$source_directory"
  case "${1:-all}" in
    (all) __rvm_current_patch_names patches ;;
    (*) patches=( "$@" ) ;;
  esac
  rvm_debug "All found patches(${#patches[*]}): ${patches[*]}."

  if
    [[ -n "${rvm_ruby_name:-${detected_rvm_ruby_name:-}}" ]] &&
    [[ "${rvm_configure_flags[*]}${patches[*]}" == "" ]]
  then
    rvm_error "\
Warning: Installing named ruby without patches, you might need to consider adding extra flags/patches like:
    --patch falcon
    --patch railsexpress
    --patch float_warnings
Options starting: '--with*' '--disable*' '--enable*' are passed to rubys './configure', also anything after '--'."
  fi

  for patch_name in "${patches[@]}"
  do
    if __rvm_string_match "${patch_name}" "*${patch_level_separator}*"
    then patch_level="${patch_name##*${patch_level_separator}}"
    else patch_level=1
    fi
    patch_name="${patch_name%${patch_level_separator}*}"

    full_patch_path="$(__rvm_lookup_full_patch_path "$patch_name")"
    rvm_debug "Patch full path '$full_patch_path'."
    if
      [[ -z "${full_patch_path:-}" ]]
    then
      rvm_warn "Patch '$patch_name' not found."
      result=1
    elif
      ! __rvm_apply_patch "${patch_name}" "$full_patch_path" "$patch_fuzziness" "$patch_level"
    then
      result=1
    fi
  done
  __rvm_cd "${_save_dir}"
  return ${result:-0}
}

__rvm_apply_patch_prepare()
{
  if
    __rvm_string_match "${_full_patch_path}" "http://*" "https://*"
  then
    _local_patch_path="$(
      mktemp ${TMPDIR:-/tmp}/tmp.XXXXXXXXXXXXXXXXXX
    )"
    rvm_log "Fetching patch ${_full_patch_path}"
    __rvm_curl --create-dirs -sS -C - -o "${_local_patch_path}" "${_full_patch_path}"
  else
    _local_patch_path="${_full_patch_path}"
  fi
}

__rvm_apply_patch_remove()
{
  if
    __rvm_string_match "${_full_patch_path}" "http://*" "https://*"
  then
    \rm -f "${_local_patch_path}"
  fi
}

__rvm_apply_patch()
{
  typeset _patch_name _full_patch_path _local_patch_path _patch_fuzziness _patch_level
  _patch_name="$1"
  _full_patch_path="$2"
  _patch_fuzziness="$3"
  _patch_level="$4"

  if
    [[ -r "patches.list" ]] &&
    __rvm_grep "${_patch_name}" "patches.list" >/dev/null
  then
    rvm_warn "Patch ${_patch_name} was already applied."
  else
    __rvm_apply_patch_prepare
    touch "patches.list"
    __rvm_log_command "patch.apply.${_patch_name##*\/}" "Applying patch ${_full_patch_path}" \
      __rvm_patch -F ${_patch_fuzziness} -p${_patch_level} -N -f -i "${_local_patch_path}" &&
    printf "%b" "${_patch_name}\n" >> "patches.list"
    __rvm_apply_patch_remove
  fi
}

__rvm_install_source()
{
  true ${rvm_ruby_selected_flag:=0}

  typeset directory db_configure_flags
  typeset -a autoconf_flags

  (( rvm_ruby_selected_flag )) || __rvm_select

  if [[ -n "${DYLD_LIBRARY_PATH:-}" ]]
  then rvm_error "Warning: DYLD_LIBRARY_PATH environment variable is set, this might interact with the compilation and ruby."
  fi

  rvm_log "Installing Ruby from source to: $rvm_ruby_home, this may take a while depending on your cpu(s)..."
  __rvm_cd "${rvm_src_path}"

  __rvm_fetch_ruby ||
  {
    result=$?
    rvm_error "There has been an error fetching the ruby interpreter. Halting the installation."
    return $result
  }

  __rvm_cd "${rvm_src_path}/$rvm_ruby_string" ||
  {
    result=$?
    rvm_error "Source directory is missing.  \nDid the download or extraction fail?  \nHalting the installation."
    return $result
  }

  if
    [[ -d "${rvm_path}/usr" ]]
  then
    __rvm_add_to_path prepend "${rvm_path}/usr/bin"
    builtin hash -r
  fi

  __rvm_apply_patches ||
  {
    result="$?"
    rvm_error "There has been an error applying the specified patches. Halting the installation."
    return $result
  }

  if
    (( ${rvm_force_autoconf_flag:-0} == 1 )) || {
      [[ -z "${rvm_ruby_configure:-}" ]] &&
      [[ ! -s "${rvm_src_path}/$rvm_ruby_string/configure" ||
        "${rvm_src_path}/$rvm_ruby_string/configure.in" -nt "${rvm_src_path}/$rvm_ruby_string/configure"
      ]]
    }
  then
    (( ${rvm_force_autoconf_flag:-0} == 1 )) &&
      autoconf_flags+=( -f )
    __rvm_log_command "autoreconf" "$rvm_ruby_string - #autoreconf${autoconf_flags:-}" __rvm_autoreconf "${autoconf_flags[@]}"
  fi

  if
    [[ -n "${rvm_ruby_configure:-""}" ]]
  then
    __rvm_log_command "configure" "$rvm_ruby_string - #configuring" "$rvm_ruby_configure" ||
    {
      result=$?
      rvm_error "There has been an error while configuring. Halting the installation."
      return $result
    }
  elif
    [[ -s ./configure ]]
  then
    rvm_configure_flags=( --prefix="$rvm_ruby_home"  "${rvm_configure_flags[@]}" )

    __rvm_db "${rvm_ruby_interpreter}_configure_flags" db_configure_flags
    if [[ -n "${ZSH_VERSION:-}" ]]
    then rvm_configure_flags=( ${=db_configure_flags} "${rvm_configure_flags[@]}" )
    else rvm_configure_flags=( ${db_configure_flags}  "${rvm_configure_flags[@]}" )
    fi
    __rvm_array_prepend_or_ignore rvm_configure_env   CFLAGS= " " "-O3" "-O"
    __rvm_array_prepend_or_ignore rvm_configure_env  CCFLAGS= " " "-O3" "-O"
    __rvm_array_prepend_or_ignore rvm_configure_env CXXFLAGS= " " "-O3" "-O"
    __rvm_log_command "configure" "$rvm_ruby_string - #configuring" \
      "${rvm_configure_env[@]}" ./configure "${rvm_configure_flags[@]}" ||
    {
      result=$?
      rvm_error "There has been an error while running configure. Halting the installation."
      return $result
    }
  else
    rvm_error "Skipping configure step, 'configure' does not exist, did autoreconf not run successfully?"
  fi

  if
    is_a_function __rvm_post_configure_${rvm_ruby_interpreter}
  then
    __rvm_log_command "postconfigure" "$rvm_ruby_string - #post-configuration" \
      __rvm_post_configure_${rvm_ruby_interpreter}
  fi

  __rvm_log_command "make" "$rvm_ruby_string - #compiling" ${rvm_ruby_make:-__rvm_make} "${rvm_make_flags[@]}" ||
  {
    result=$?
    rvm_error "There has been an error while running make. Halting the installation."
    return $result
  }

  __rvm_rm_rf "$PWD/.ext/rdoc" # WTF?

  rvm_ruby_make_install=${rvm_ruby_make_install:-"__rvm_make install"}

  __rvm_run "install" "$rvm_ruby_make_install" "$rvm_ruby_string - #installing" ||
  {
    result=$?
    rvm_error "There has been an error while running make install. Halting the installation."
    return $result
  }

  if [[ -s "${rvm_src_path}/$rvm_ruby_string/patches.list" ]]
  then __rvm_cp -f "${rvm_src_path}/$rvm_ruby_string/patches.list" "$rvm_ruby_home/patches.list"
  fi

  case "${rvm_ruby_string:-""}" in
    ruby-1.8.4|ruby-1.8.5-*)
      typeset libdir
      libdir="$rvm_ruby_home/lib"
      if
        [[ -d "${libdir}64" ]]
      then
        \rm -rf "${libdir}"
        ln -s "${libdir}64" "${libdir}"
      fi
    ;;
  esac

  case " ${rvm_configure_flags[*]} " in
    (*[[:space:]]--program-suffix=*)
      typeset program_suffix
      program_suffix="${rvm_configure_flags[*]}"
      program_suffix="${program_suffix#*--program-suffix=}"
      program_suffix="${program_suffix%%[\' ]*}"
      __rvm_log_command "link.ruby" "$rvm_ruby_string - #linking ruby${program_suffix} -> ruby " \
        ln -s "$rvm_ruby_home/bin/ruby${program_suffix}" "$rvm_ruby_home/bin/ruby"
      ;;
  esac

  rvm_create_flag=1 __rvm_use &&
    ( rubygems_setup ${rvm_rubygems_version:-latest} ) && # () for exit in rubygems_fatal_error
    __rvm_generate_wrappers &&
    __rvm_log_command "chmod.bin" "" chmod +x "$rvm_ruby_home/bin"/* &&
    __rvm_post_install ||
    return $?

  __rvm_fetch_ruby_cleanup

  rvm_log "Install of $rvm_ruby_string - #complete "
}

__rvm_install_ruby_try_remote()
{
  : rvm_disable_binary_flag:${rvm_disable_binary_flag:=0}: rvm_remote_flag:${rvm_remote_flag:=0}:
  if
    (( rvm_remote_flag > 0 )) || # remote flag wins!
    (( rvm_head_flag == 0 && rvm_disable_binary_flag == 0 )) # not a head and disabled binary
  then
    rvm_log "Searching for binary rubies, this might take some time."
    typeset __rvm_ruby_url __rvm_ruby_verify_download_flag
    __rvm_ruby_url="$( __rvm_remote_server_path "${rvm_ruby_string}" )"
    IFS=: read __rvm_ruby_verify_download_flag __rvm_ruby_url <<<"${__rvm_ruby_url}"
    if
      (( ${rvm_verify_downloads_flag:-1} > ${__rvm_ruby_verify_download_flag:=0} ))
    then
      __rvm_ruby_verify_download_flag=${rvm_verify_downloads_flag}
    fi
    if
      [[ -z "${__rvm_ruby_url}" ]]
    then
        if
          (( rvm_remote_flag ))
        then
          rvm_error "Requested binary installation but no rubies are available to download, consider skipping --binary flag."
          return 1
        else
          rvm_warn "No binary rubies available for: $(__rvm_system_path -)/${rvm_ruby_string}.
Continuing with compilation. Please read 'rvm help mount' to get more information on binary rubies."
        fi
    else
      rvm_log "Found remote file ${__rvm_ruby_url}"
      __rvm_setup_compile_environment_setup
      __rvm_setup_compile_environment_requirements "${rvm_ruby_string}" || return 1
        if
          rvm_verify_downloads_flag=${__rvm_ruby_verify_download_flag} rvm_remote_flag=1 "${rvm_scripts_path}/external" mount "${__rvm_ruby_url}" "${rvm_ruby_string}"
        then
          return 0
        else
          __rvm_rm_rf "$rvm_rubies_path/$rvm_ruby_string" # cleanup so standard installation works
          rvm_warn "Mounting remote ruby failed, trying to compile."
        fi
    fi
  fi
  return 2 # continue with compilation
}

__rvm_install_ruby()
{
  true ${rvm_head_flag:=0} ${rvm_ruby_selected_flag:=0}
  typeset binary __rvm_ruby_name ruby_install_type

  if
    (( rvm_ruby_selected_flag == 0 ))
  then
    __rvm_ruby_name="$rvm_ruby_name"
    __rvm_select || return $?
    if
      [[ -n "$__rvm_ruby_name" ]]
    then
      __rvm_select || return $? # second detection for -n verification
      if
        [[ "$__rvm_ruby_name" != "$detected_rvm_ruby_name" ]]
      then
        rvm_error "
The used ruby name (-n) is not valid, it was matched as:

$( env | __rvm_grep "^rvm.*=$__rvm_ruby_name$" || printf "# Was not used at all\n")

for more details on selecting names please visit:
https://rvm.io/rubies/named/
" #" fix escaping
        return 1
      fi
    fi
  fi

  if [[ -n "${RUBYOPT:-""}" ]]
  then
    ruby_options="$RUBYOPT"
    unset RUBYOPT
  fi

  __rvm_select_late

  if __rvm_install_ruby_try_remote
  then return 0
  else (( $? == 2 )) || return 1 # 2 => continue with compilation
  fi

  __rvm_check_for_compiler || return $?

  case "${rvm_ruby_interpreter}" in
    opal|macruby|ree|jruby|maglev|goruby|rubinius|ironruby|ruby|mruby|topaz)
      ruby_install_type=$rvm_ruby_interpreter
      ;;
    rbx)      ruby_install_type=rubinius ;;
    ir)       ruby_install_type=ironruby ;;
    kiji|tcs|jamesgolick) ruby_install_type=ruby     ;;
    default)
      rvm_error "a ruby interpreter to install must be specified and not simply 'default'."
      ;;
    *)
      rvm_error "Either the ruby interpreter is unknown or there was an error!."
      ;;
  esac

  export -a rvm_configure_env
  [[ -n "${rvm_configure_env[*]}" ]] || rvm_configure_env=() # zsh can assume empty var => ( '' )

  source "$rvm_scripts_path/functions/manage/${ruby_install_type}"
  ${ruby_install_type}_install || return $?

  # Record the Ruby's configuration to a file, key=value format.
  __rvm_ruby_config_save "$rvm_ruby_home/bin/ruby"
  __rvm_fix_group_permissions "$rvm_ruby_home"

  rvm_hook="after_install"
  source "$rvm_scripts_path/hook"

  if [[ -n "$ruby_options" ]]
  then
    RUBYOPT="$ruby_options"
    export RUBYOPT
  fi
}

__rvm_check_default()
{
  typeset default_ruby_interpreter current_ruby_interpreter
  default_ruby_interpreter="$( rvm alias show default 2>/dev/null )"
  default_ruby_interpreter="${default_ruby_interpreter%%${rvm_gemset_separator:-"@"}*}"
  current_ruby_interpreter="${rvm_ruby_string%%${rvm_gemset_separator:-"@"}*}"
  if
    [[ -n "$current_ruby_interpreter" ]] &&
    [[ "$current_ruby_interpreter" == "$default_ruby_interpreter" ]]
  then
    __rvm_log_command 'default.restore' 'Removing default ruby interpreter' \
      rvm use system --default
  fi
}

__rvm_uninstall_ruby()
{
  __rvm_remove_ruby uninstall
}

__rvm_remove_ruby()
{
  case "${rvm_ruby_string:-}" in
    (*@*)
      rvm_error "'rvm remove' does not work with gemsets, use '--gems' to remove all gemsets or
'rvm ${rvm_ruby_string%@*} do rvm gemset remove ${rvm_ruby_string#*@}' to remove the '${rvm_ruby_string#*@}' gemset."
      return 1
      ;;
  esac
  (( ${rvm_ruby_selected_flag:=0} )) || __rvm_select
  [[ -n "${rvm_ruby_string:-}"    ]] ||
  {
    rvm_error "Cannot ${1:-remove} unknown package '$rvm_ruby_string'"
    return 1
  }

  typeset _dir
  for _dir in "${rvm_src_path}" "${rvm_rubies_path}"
  do
    if
      [[ -d "${_dir}/$rvm_ruby_string" ]]
    then
      __rvm_log_command "remove.${_dir##*/}" "Removing ${_dir}/$rvm_ruby_string" __rvm_rm_rf "${_dir}/$rvm_ruby_string"
    else
      rvm_log "${_dir}/$rvm_ruby_string has already been removed."
    fi
  done

  if
    [[ -e "${rvm_bin_path}/$rvm_ruby_string" ]]
  then
    \rm -f "${rvm_bin_path}/$rvm_ruby_string"
  fi

  __rvm_remove_install_record "$rvm_ruby_string"
  case "${1:-remove}" in
    (remove)
      __rvm_remove_gemsets
      __rvm_remove_archives
      __rvm_remove_aliases
      __rvm_remove_wrappers
      __rvm_remove_environments
      __rvm_remove_binaries
      ;;
    (uninstall)
      __rvm_remove_gemsets
      __rvm_check_default
      ;;
    (reinstall)
      true # nothing more to do here!
      ;;
  esac
  unset rvm_remove_flag
}

__rvm_reinstall_ruby()
{
  __rvm_remove_ruby reinstall &&
  __rvm_install_ruby "$@" &&
  __rvm_gemset_pristine_all "$rvm_ruby_string"
}

__rvm_gemset_pristine_all()
{
  typeset -a destination_gemsets
  typeset destination_gemset
  __rvm_read_lines destination_gemsets <(
    "$rvm_scripts_path/list" gemsets strings | __rvm_grep -E "^$1(@.*)?$"
  )
  for destination_gemset in "${destination_gemsets[@]}"
  do __rvm_gemset_pristine "$destination_gemset"
  done
}

__rvm_remove_gemsets__()
{
  typeset gemset
  typeset -a gemsets
  __rvm_read_lines gemsets <(
    __rvm_find -L "${rvm_gems_path:-"$rvm_path/gems"}" -maxdepth 1 \
      "${name_opt}" "${rvm_ruby_string}" -o \
      "${name_opt}" "${rvm_ruby_string}@*"
  )
  for gemset in "${gemsets[@]}"
  do
    printf "Removing $gemset - "
    __rvm_rm_rf "$gemset" && printf "ok\n" ||
    {
      typeset __res=$?
      echo "failed\n"
      return ${__res}
    }
  done
}

__rvm_remove_gemsets()
{
  if
    (( ${rvm_gems_flag:=0} == 1 ))
  then
    __rvm_log_command remove_gemsets "Removing $rvm_ruby_string gemsets" __rvm_remove_gemsets__ ||
      return $?
  fi
  true # for OSX
}

__rvm_remove_wrappers()
{
  rvm_log "Removing $rvm_ruby_string wrappers..."
  typeset -a wrappers
  typeset wrapper

  __rvm_read_lines wrappers <(
    __rvm_find "$rvm_wrappers_path" -maxdepth 1 -mindepth 1 -type d "${name_opt}" "*$rvm_ruby_string*" 2>/dev/null
    __rvm_find "$rvm_bin_path" -maxdepth 1 -mindepth 1 "${name_opt}" "*-$rvm_ruby_string" 2>/dev/null
  )
  for wrapper in "${wrappers[@]}"
  do
    __rvm_rm_rf "$wrapper"
  done
}

__rvm_remove_environments()
{
  rvm_log "Removing $rvm_ruby_string environments..."
  typeset environments environment

  environments=($(__rvm_find "$rvm_environments_path" -maxdepth 1 -mindepth 1 -type f "${name_opt}" "*$rvm_ruby_string*" ))
  for environment in "${environments[@]}"
  do
    if [[ -e "$environment" ]]
    then __rvm_rm_rf "$environment"
    fi
  done
}

__rvm_remove_aliases()
{
  rvm_log "Removing $rvm_ruby_string aliases..."
  typeset alias_name aliases

  aliases=($(__rvm_awk '/'$rvm_ruby_string'/{print}' "$rvm_path/config/alias" | __rvm_sed 's/=.*//'))
  for alias_name in "${aliases[@]}"
  do
    # Remove from alias key-value store
    "$rvm_scripts_path/alias" delete "$alias_name" >/dev/null 2>&1
  done
}

__rvm_remove_archives()
{
  if (( ${rvm_archive_flag:=0} == 1 ))
  then
    rvm_log "Removing $rvm_ruby_string archives..."
    \rm -f ${rvm_archives_path}/${rvm_ruby_package_file}.*
  fi
}

# Iterate over all binaries and check for symlinked wrappers etc.
__rvm_remove_binaries()
{
  rvm_log "Removing $rvm_ruby_string binaries..."
  typeset full_binary_path linked_binary_path
  typeset -a binaries

  __rvm_read_lines binaries <(
    __rvm_find "${rvm_bin_path:-$rvm_path/bin}" -maxdepth 1 -mindepth 1 "${name_opt}" "*$rvm_ruby_string" -or "${name_opt}" "*$rvm_ruby_string@*"
  )
  for full_binary_path in "${binaries[@]}"
  do
    if
      [[ -L "$full_binary_path" ]] &&
      __rvm_string_match "$(__rvm_readlink "$full_binary_path")" "*$rvm_ruby_string/*" "*$rvm_ruby_string@*"
    then
      \rm -f "$full_binary_path"
    fi
  done
}

__rvm_post_install()
{
  case "$rvm_ruby_interpreter" in
  (jruby|ree|rbx|mruby|macruby) true ;; #skip
  (*)
    (( ${#binaries[@]} )) || binaries=(gem irb erb ri rdoc testrb rake)
    ;;
  esac

  if
    (( ${#binaries[@]} ))
  then
    rvm_log "$rvm_ruby_string - #adjusting #shebangs for (${binaries[@]})."
    for binary in "${binaries[@]}"
    do
      if
        [[ -e "$rvm_ruby_home/bin/$binary" || -e "${rvm_src_path}/$rvm_ruby_string/bin/$binary" ]]
      then
        if
          [[ "${rvm_src_path}/$rvm_ruby_string" != "$rvm_ruby_home" ]] &&
          [[ -f "${rvm_src_path}/$rvm_ruby_string/bin/$binary" && ! -L "$rvm_ruby_home/bin/$binary" ]]
        then
          __rvm_cp -f "${rvm_src_path}/$rvm_ruby_string/bin/$binary" "$rvm_ruby_home/bin/$binary"
        elif
          [[ -f "$rvm_ruby_gem_home/bin/$binary" ]]
        then
          __rvm_cp -f "$rvm_ruby_gem_home/bin/$binary" "$rvm_ruby_home/bin/$binary"
        fi
        __rvm_inject_ruby_shebang "$rvm_ruby_home/bin/$binary"
        chmod +x "$rvm_ruby_home/bin/$binary"
      fi
    done
  fi
  binaries=(gem irb erb ri rdoc testrb rake) #reset
  __rvm_gemsets_initial
  __rvm_irbrc
}

__rvm_inject_ruby_shebang()
{
  typeset actual_file="$1"
  __rvm_readlink_deep actual_file
  if
    [[ -f "$actual_file" ]]
  then
    __rvm_sed_i "${actual_file}" -e '1,1s=.*=#!'"/usr/bin/env ruby="
    [[ -x "$actual_file" ]] || chmod +x "$actual_file"
  fi
}

__rvm_manage_rubies()
{
  typeset manage_result bin_line current_ruby_string
  typeset -a rubies
  rubies=()

  rvm_gemset_name=""
  rvm_ruby_selected_flag=0
  rvm_ruby_gem_home="${rvm_ruby_gem_home:-""//${rvm_gemset_separator:-"@"}*}"
  rvm_ruby_string="${rvm_ruby_string:-""//${rvm_gemset_separator:-"@"}*}"

  # Given list of ruby strings.
  if
    __rvm_string_match "${rubies_string:-}" "old:*"
  then
    typeset _older_then
    _older_then=${rubies_string#old:}
    if
      [[ -z "${_older_then}" ]]
    then
      # minified https://github.com/mpapis/home_dotfiles/blob/master/bin/git-summary#L5-L50
      case "${_system_type}" in
        (Darwin) _older_then="$( __rvm_date -j -v6m           +%F )" ;;
        (*)      _older_then="$( __rvm_date --date="-6months" +%F )" ;;
      esac
    fi
    __rvm_read_lines rubies <(
      __rvm_cd "$rvm_rubies_path"
      # find on bsd does not have -not, we need to use \!
      __rvm_find . -maxdepth 1 -mindepth 1 -type d \! -newermt $_older_then 2>/dev/null | cut -c 3-
    )
    (( ${#rubies[*]} )) ||
    {
      rvm_warn "No rubies older then ${_older_then}."
      return 1
    }
    __rvm_ask_for "Are you SURE you wish to '$action' ${rubies[*]}?" yes || return $?
  elif
    [[ -n "${rubies_string:-}" && "${rubies_string}" != "all" ]]
  then
    __rvm_custom_separated_array rubies , "${rubies_string}"
  elif
    [[ "$action" == "install" ]]
  then
    rvm_error 'Really? '"$action"', all? See "rvm list known" and limit the selection to something more sane please :)'
    return 1
  elif
    [[ -z "${rubies_string}" ]]
  then
    rvm_error 'Really? '"$action"', all? See "rvm list" and limit the selection to something more sane please :)'
    return 1
  else
    # explicit all && not install
    if
      (( ${rvm_force_flag:-0} == 0 )) &&
      [[ "$action" == "reinstall" || "$action" == "remove" || "$action" == "uninstall" ]]
    then
      __rvm_ask_for "Are you SURE you wish to '$action' all rubies?" yes || return $?
    fi
    __rvm_read_lines rubies <(
      __rvm_cd "$rvm_rubies_path"
      __rvm_find . -maxdepth 1 -mindepth 1 -type d 2>/dev/null | cut -c 3-
    )
  fi

  for rvm_ruby_string in "${rubies[@]}"
  do
    rvm_debug "${rvm_ruby_string} - $action"
    current_ruby_string="$rvm_ruby_string"
    if
      # in () so it does not mess with env. variables
      (
        rvm_hook="before_install"
        source "$rvm_scripts_path/hook"
        __rvm_${action}_ruby
      )
    then
      if [[ "$action" == "install" ]]
      then __rvm_record_install "$current_ruby_string"
      fi
    else
      : manage_result:${manage_result:=$?}
    fi
  done
  return "${manage_result:-0}"
}
