#!/usr/bin/env bash

source "$rvm_path/scripts/base"

rvm_ruby_gem_home="${rvm_ruby_gem_home:-$GEM_HOME}"

if [[ ! -d "$rvm_ruby_gem_home" ]] && command -v gem > /dev/null 2>&1; then rvm_ruby_gem_home="$(gem env home)" ; fi

usage()
{
  printf "
  Usage:

    rvm gemset [action]

  Action:

    {import,export,create,copy,rename,empty,delete,name,dir,list,gemdir,install,pristine,clear,use,update,unpack,globalcache}

  Description:

    Commands for working with and manipulating gemsets within RVM.

"
}

gemset_update()
{

  if [[ -z "$rvm_ruby_strings" ]]; then

    "$rvm_path/scripts/log" "info" "Running gem update for all rubies and gemsets."

    rvm_ruby_strings="$(
      builtin cd "${rvm_gems_path:-"$rvm_path/gems"}" ;
      find . -maxdepth 1 -mindepth 1 -type d -print 2>/dev/null \
        | grep -v '^\(doc\|cache\|@\|system\)' | \tr '\n' ','
    )"

    rvm_ruby_strings="${rvm_ruby_strings/%,}"

    rvm_ruby_strings="${rvm_ruby_strings//.\/}"

  else
    "$rvm_path/scripts/log" "info" "Running gem update for the specified rubies."
  fi

  export rvm_ruby_strings

  "$rvm_path/scripts/set" "gem" "update"

  return $?
}

gemset_globalcache()
{
  local gc_status globalcache_enabled directories directory_name full_directory_path directory_name

  if [[ "$1" == "enabled" ]]; then

    __rvm_using_gemset_globalcache

    globalcache_enabled=$?

    gc_status="Unknown"

    if [[ $globalcache_enabled -eq 0 ]]; then
      gc_status="Enabled"
    else
      gc_status="Disabled"
    fi

    "$rvm_path/scripts/log" "info" \
      "Gemset global cache is currently: $gc_status"

    return "$globalcache_enabled"

  elif [[ "$1" == "disable" ]]; then

    "$rvm_path/scripts/log" "info" \
      "Removing the global cache (note: this will empty the caches)"

    directories=($(
      builtin cd "${rvm_gems_path:-"$rvm_path/gems"}" ;
      find . -maxdepth 1 -mindepth 1 -type d -print)
    )

    for directory_name in "${directories[@]//.\/}"; do

      current_cache_path="${rvm_gems_path:-"$rvm_path/gems"}/$directory_name/cache"

      if [[ -L "$current_cache_path" \
        && "$(readlink "$current_cache_path")" == "$rvm_gems_cache_path" ]]; then

        "$rvm_path/scripts/log" "info" \
          "Reverting the gem cache for $directory_name to an empty directory."

        rm -f "$current_cache_path" 2>/dev/null

        mkdir -p "$current_cache_path" 2>/dev/null
      fi
    done

    "$rvm_path/scripts/db" "$rvm_path/config/user" \
      "use_gemset_globalcache" "delete"

  elif [[ "$1" == "enable" ]]; then

    "$rvm_path/scripts/log" "info" \
      "Enabling global cache for gems."

    mkdir -p "$rvm_gems_cache_path"

    directories=($(
      builtin cd "${rvm_gems_path:-"$rvm_path/gems"}" ;
      find . -maxdepth 1 -mindepth 1 -type d -print)
    )

    for directory_name in "${directories[@]//.\/}" ; do

      current_cache_path="${rvm_gems_path:-"$rvm_path/gems"}/$directory_name/cache"

      if [[ -d "$current_cache_path" && ! -L "$current_cache_path" ]]; then

        "$rvm_path/scripts/log" "info" \
          "Moving the gem cache for $directory_name to the global cache."

        mv "$current_cache_path/"*.gem "$rvm_gems_cache_path/" 2>/dev/null

        rm -rf "$current_cache_path"

        ln -nfs "$rvm_gems_cache_path" "$current_cache_path"
      fi

    done

    "$rvm_path/scripts/db" "$rvm_path/config/user" \
      "use_gemset_globalcache" "true"

  else
    printf "

  Usage:

    rvm gemset globalcache {enable,disable}

    Enable / Disable the use of a global gem cachedir.

"
    return 1
  fi
}

gemset_name()
{
  gemset_dir |  awk -F${rvm_gemset_separator:-"@"} '{print $2}'
  return $?
}

gemset_dir()
{
  echo "$rvm_ruby_gem_home"
  return $?
}

gemset_create()
{
  local gem_home gemset gemsets prefix

  if [[ -n "$rvm_ruby_string" ]] ; then
    __rvm_select
  fi

  prefix=$(echo $rvm_ruby_gem_home | sed 's/'${rvm_gemset_separator:-"@"}'.*$//')

  gemsets=(${args[@]})

  for gemset in "${gemsets[@]}" ; do

    if [[ "$gemset" == *"${rvm_gemset_separator:-"@"}"* ]]; then
      "$rvm_path/scripts/log" "error" \
        "Can not create gemset '$gemset', it contains a \"${rvm_gemset_separator:-"@"}\"."
      continue
    fi

    if [[ -z "$gemset" || "$gemset" = *"${rvm_gemset_separator:-"@"}" ]] ; then
      "$rvm_path/scripts/log" "error" \
        "Can not create gemset '$gemset', Missing name. "
      continue
    fi

    gem_home="${prefix}${rvm_gemset_separator:-"@"}${gemset}"

    if [[ ! -d "$gem_home" ]] ; then
      mkdir -p "$gem_home"
    fi

    # When the globalcache is enabled, we need to ensure we setup the cache directory correctly.
    if __rvm_using_gemset_globalcache ; then

      if [[ -d "$gem_home/cache" && ! -L "$gem_home/cache" ]]; then

        mv "$gem_home/cache"/*.gem "$rvm_gems_cache_path/" 2>/dev/null

        rm -rf "$gem_home/cache"
      fi

      ln -nfs "$rvm_gems_cache_path" "$gem_home/cache"
    fi

    "$rvm_path/scripts/log" "info" "'$gemset' gemset created ($gem_home)."
  done

  return 0
}

gemset_list()
{
  if [[ ${rvm_ruby_selected_flag:-0} -eq 0 ]] ; then __rvm_select ; fi

  "$rvm_path/scripts/log" "info" \
    "\ngemsets for $rvm_ruby_string (found in ${rvm_gems_path:-"$rvm_path/gems"}/$rvm_ruby_string)"

  if [[ -d "${rvm_gems_path:-"$rvm_path/gems"}" ]] ; then

    if [[ -n "${rvm_ruby_string:-""}" ]] ; then

      ls "${rvm_gems_path:-"$rvm_path/gems"}/" \
        | awk -F"${rvm_gemset_separator:-"@"}" \
        "/${rvm_ruby_string}${rvm_gemset_separator:-"@"}/{print \$2}" \
        2>/dev/null

    else
      "$rvm_path/scripts/log" "error" \
        "\$rvm_ruby_string is not set!"
      return 1
    fi

  else
    "$rvm_path/scripts/log" "error" \
      "${rvm_gems_path:-"$rvm_path/gems"} does not exist!"
    return 1
  fi
  printf "\n"

  return 0
}

gemset_delete()
{
  gemsets=(${args[@]})

  if [[ ${rvm_ruby_selected_flag:-0} -eq 0 ]] ; then __rvm_select ; fi

  if [[ -n "${gemsets[__array_start]}" ]] ; then
    rvm_gemset_name="${gemsets[__array_start]}"
  fi

  if [[ -n "$rvm_gemset_name" ]] ; then

    gemdir="${rvm_gems_path:-"$rvm_path/gems"}/$rvm_ruby_string${rvm_gemset_separator:-"@"}$rvm_gemset_name"

    if [[ -d "$gemdir" && "$gemdir" != '/' && ${rvm_force_flag:-0} -gt 0 ]] ; then

      rm -rf  "$gemdir"

    elif [[ -d "$gemdir" ]] ; then

      "$rvm_path/scripts/log" "warn" \
        "Are you SURE you wish to remove the entire gemset directory '$rvm_gemset_name' ($gemdir)?"

      printf "(anything other than 'yes' will cancel) > "

      read response

      if [[ "yes" = "$response" ]] ; then

        if [[ -L "$gemdir/cache" ]] ; then
          rm -f "$gemdir/cache"
        fi

        rm -rf "$gemdir"

      else
        "$rvm_path/scripts/log" "info" \
          "Not doing anything, phew... close call that one eh?"
      fi

    else
      "$rvm_path/scripts/log" "info" \
        "$gemdir already does not exist."
    fi

  else
    "$rvm_path/scripts/log" "error" \
      "A gemset name must be specified in order to delete a gems."
    return 1
  fi

  return 0
}

gemset_empty()
{
  local gemdir

  if [[ -z "${rvm_ruby_gem_home:-""}" ]] ; then __rvm_select ; fi

  gemdir="$rvm_ruby_gem_home"

  if [[ -d "$gemdir" && "$gemdir" != '/' && ${rvm_force_flag:-0} -gt 0 ]] ; then

    builtin cd "$gemdir" && rm -rf ./bin/* ./doc/* ./gems/* ./specifications/*

  elif [[ -d "$gemdir" ]] ; then

    "$rvm_path/scripts/log" "warn" \
      "Are you SURE you wish to remove the installed gemset for gemset '$(basename "$gemdir")' ($gemdir)?"

    echo -n "(anything other than 'yes' will cancel) > "

    read response

    if [[ "yes" = "$response" ]] ; then

      builtin cd "$gemdir" && rm -rf ./bin/* ./doc/* ./gems/* ./specifications/*

    else
      "$rvm_path/scripts/log" "info" \
        "Not doing anything, phew... close call that one eh?"
    fi

  else
    "$rvm_path/scripts/log" "info" \
      "$gemdir already does not exist."
  fi

  return 0
}

# Migrate gemsets from ruby X to ruby Y
gemset_copy()
{
  local source_ruby destination_ruby source_path destination_path

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

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

  if [[ -z "$destination_ruby" || -z "$source_ruby" ]] ; then
    "$rvm_path/scripts/log" "error" "Source and destination must be specified: 'rvm gemset copy X Y'"
    return 1
  fi

  # TODO: Account for more possibilities:
  #   rvm gemset copy 1.9.2 @gemsetb        # From 1.9.2 default to current ruby, 1.9.2 exists.
  #   rvm gemset copy @gemseta @gemsetb     # Current ruby, gemseta exists.
  #   rvm gemset copy gemseta gemsetb       # Currenty Ruby, gemseta exists.
  #   rvm gemset copy gemseta 1.8.7@gemsetb # Currenty Ruby@gemseta, current ruby@gemseta exists.

  source_path="$(rvm_silence_logging=1 rvm "$source_ruby" gem env gemdir)"

  destination_path="$(rvm_silence_logging=1 rvm "$destination_ruby" gem env gemdir)"

  if [[ -z "$source_path" || ! -d "$source_path" ]]; then
    "$rvm_path/scripts/log" "error" \
      "Unable to expand '$source_ruby' or directory does not exist."
    return 1
  fi

  if [[ -z "$destination_path" ]]; then
    "$rvm_path/scripts/log" "error" \
      "Unable to expand '$destination_ruby'"
    return 1
  fi

  if [[ -d "$source_path" ]] ; then

    "$rvm_path/scripts/log" "info" "Copying gemset from $source_ruby to $destination_ruby"

    for dir in bin doc gems specifications cache ; do

      mkdir -p "$destination_path/$dir"

      if [[ -d "$source_path/$dir" ]] ; then
        cp -Rf "$source_path/$dir" "$destination_path/"

      elif [[ -L "$source_path/$dir" ]] ; then
        cp "$source_path/$dir" "$destination_path/$dir"
      fi

    done

    "$rvm_path/scripts/log" "info" \
      "Making gemset for $destination_ruby pristine."

    __rvm_run_with_env "gemset.pristine" "$destination_ruby" "rvm gemset pristine"

  else
    "$rvm_path/scripts/log" "error" \
      "Gems directory does not exist for $source_path ($source_path)"
    return 1
  fi
}

# Migrate gemsets from ruby X to ruby Y
gemset_rename()
{
  local source_name destination_name source_path destination_path

  source_name="${args[__array_start]:-""}"
  args[$__array_start]="" ; args=(${args[@]})

  destination_name="${args[__array_start]:-""}"
  args[$__array_start]="" ; args=(${args[@]})

  if [[ -z "$destination_name" || -z "$source_name" ]] ; then
    "$rvm_path/scripts/log" "error" \
      "Source and destination gemsets must be specified: 'rvm gemset rename X Y'"
    return 1
  fi

  source_path="$(rvm_silence_logging=1 rvm "@$source_name" gem env gemdir)"

  if [[ -z "$source_path" || ! -d "$source_path" ]]; then
    "$rvm_path/scripts/log" "error" \
      "'$source_name' does not exist."
    return 1
  fi

  destination_path=${source_path/%$source_name/$destination_name}

  if [[ -d "$source_path" ]] ; then

    if [[ ! -d "$destination_path" ]] ; then

      mv "$source_path" "$destination_path"

    else

      "$rvm_path/scripts/log" "error" \
        "Gemset $destination_name already exists!"

      return 1

    fi

  else

    "$rvm_path/scripts/log" "error" \
      "Gems directory does not exist for $source_path ($source_path)"

    return 1

  fi
}


gemset_unpack()
{
  local gems name directory version versions

  directory="${args[$__array_start]}"

  if [[ -z "$directory" ]] ; then
    directory="vendor/gems"
  fi

  if [[ -n "$rvm_ruby_gem_home" ]] ; then
    export GEM_HOME="$rvm_ruby_gem_home"
    export GEM_PATH="$rvm_ruby_gem_home/bin:$rvm_ruby_global_gems_path/bin"
    export BUNDLE_PATH="$rvm_ruby_gem_home"
  fi

  "$rvm_path/scripts/log" "info" \
    "Unpacking current environments gemset to ${directory}\n"

  unset -f gem

  gems=($(command gem list | sed 's#[\(|\)]##g' | sed -e 's#, #,#g' -e 's/ /;/g'))

  for gem in ${gems[@]} ; do

    name="${gem/;*/}"

    versions="${gem/*;/}" ; versions=(${versions//,/ })

    for version in "${versions[@]}" ; do

      ( command gem unpack "$name" -v"$version" --target "$directory" )&

    done

  done ; wait

  "$rvm_path/scripts/log" "info" \
    "Unpacking into ${directory} complete\n"

  return 0
}

gemset_export()
{
  local gems name file_name version versions

  rvm_file_name="${rvm_file_name:-${gems_args// }}"

  if [[ -n "$rvm_ruby_gem_home" ]] ; then
    export GEM_HOME="$rvm_ruby_gem_home"
    export GEM_PATH="$rvm_ruby_gem_home/bin:$rvm_ruby_global_gems_path/bin"
    export BUNDLE_PATH="$rvm_ruby_gem_home"
  fi

  if [[ -z "$rvm_file_name" ]] ; then

    if [[ -n "$rvm_gemset_name" ]] ; then
      rvm_file_name="$rvm_gemset_name.gems"

    else
      rvm_file_name="default.gems"
    fi
  fi

  "$rvm_path/scripts/log" "info" \
    "Exporting current environments gemset to $rvm_file_name"

  touch "$rvm_file_name"

  echo "# $rvm_file_name generated gem export file. Note that any env variable settings will be missing. Append these after using a ';' field separator" \
    > "$rvm_file_name"

  gems=($(gem list | sed 's#[\(|\)]##g' | sed 's#, #,#g' | tr ' ' ';'))

  for gem in "${gems[@]}" ; do

    name="${gem/;*/}"

    if [[ ${rvm_latest_flag:-0} -eq 0 ]] ; then

      versions="${gem/*;/}" ; versions="${versions//,/ }"

      for version in $versions ; do
        echo "$name -v$version" >> $rvm_file_name
      done ; unset version versions

    else
      echo "$name" >> $rvm_file_name
    fi
  done

  return 0
}

gemset_import()
{
  unset -f gem

  if [[ -n "${rvm_ruby_gem_home:-""}" ]] ; then
    export GEM_HOME="$rvm_ruby_gem_home"
    export GEM_PATH="$rvm_ruby_gem_home"
    export BUNDLE_PATH="$rvm_ruby_gem_home"
  else
    rvm_ruby_gem_home=${GEM_HOME:-$(gem env gemdir)}
  fi

  #rvm_gemset_name="${gems_args//.gem*/}"
  #rvm_gemset_name="${gems_args// /}"

  rvm_file_name="${gems_args// /}"

  # TODO: this could likely be better with find
  if [[ -s "${rvm_file_name%.gems*}.gems" ]] ; then
    rvm_file_name="${rvm_file_name%.gems*}.gems"

  elif [[ -s "${rvm_gemset_name}.gems" ]] ; then
    rvm_file_name="${rvm_gemset_name}.gems"

  elif [[ -s "default.gems" ]] ; then
    rvm_file_name="default.gems"

  elif [[ -s "system.gems" ]] ; then
    rvm_file_name="system.gems"

  elif [[ -s ".gems" ]] ; then
    rvm_file_name=".gems"

  else
    "$rvm_path/scripts/log" "error" "No *.gems file found."
    return 1
  fi

  if [[ ! -d "$rvm_ruby_gem_home/specifications/" ]] ; then
    mkdir -p "$rvm_ruby_gem_home/specifications/"
  fi

  if [[ ! -d "$rvm_gems_cache_path" ]] ; then
    mkdir -p "$rvm_gems_cache_path" # Ensure the base cache dir is initialized.
  fi

  if [[ -s "$rvm_file_name" ]] ; then

    echo "Importing  $rvm_file_name file..."

    rvm_ruby_gem_list=$(builtin cd "$rvm_ruby_gem_home/specifications/" ; find . -maxdepth 1 -mindepth 1 -type f -print 2> /dev/null | sed -e 's#.gems.*$##' 2> /dev/null)
    rvm_ruby_gem_list="${rvm_ruby_gem_list//.\/}"

    while read -r line
    do # Keep this on 2nd line :(

      if [[ -n "${line// /}" ]] ; then
        gems_args="$line" ; gem_install
      fi

    done < <(awk '/^[^#]+/{print}' "${rvm_file_name}")

  else
    "$rvm_path/scripts/log" "error" "${rvm_file_name} does not exist to import from."
  fi
}

__rvm_parse_gems_args()
{
  gem="${gems_args/;*}" ; gem_prefix=""

  if echo "$gems_args" | grep -q ';' ; then
    gem_prefix="${gems_args/*;}"
  fi

  if "$rvm_path/scripts/match" "$gem" ".gem$" ; then
    gem_name="$(basename "${gem/.gem/}" |  awk -F'-' '{$NF=NULL;print}')"
    gem_version="$(basename "${gem/.gem/}" |  awk -F'-' '{print $NF}' )"
    gem_postfix="$(basename "${gem/*.gem/}")"

  else
    gem_name="${gem/ */}"

    if "$rvm_path/scripts/match" "$gem" "--version" ; then
      gem_version="$(echo "$gem" | sed -e 's#.*--version[=]*[ ]*##' | awk '{print $1}')"
      gem_postfix="$(echo "$gem" | sed -e "s#${gem_name/ /}##" -e "s#--version[=]*[ ]*${gem_version/ /}##")"

    elif "$rvm_path/scripts/match" "$gem" "-v" ; then
      gem_version="$(echo "$gem" | sed -e 's#.*-v[=]*[ ]*##' | awk '{print $1}')"
      gem_postfix="$(echo "$gem" | sed -e "s#${gem_name/ /}##" -e "s#-v[=]*[ ]*${gem_version/ /}##")"

    else
      unset gem_version # no version
    fi
  fi

  if [[ -s "$gem" ]] ; then
    gem_file_name="$gem"

  elif "$rvm_path/scripts/match" "$gem" ".gem$" ; then
    gem_file_name="$gem"

  elif [[ -z "${gem_version/ /}" ]] ; then
    gem_file_name="${gem_name/ /}*.gem"

  else # version
    gem_file_name="${gem_name/ /}-${gem_version/ /}.gem"
  fi
}

# Install a gem
gem_install()
{
  local gem gem_prefix gem_name gem_version gem_file_name gem_postfix cache_file gem_file_name gem_string gem_action

  result=0

  # First we parse the gem args to pick apart the pieces.
  __rvm_parse_gems_args

  # Now we determine if a .gem cache file is already installed
  if [[ ${rvm_force_flag:-0} -eq 0 && -f "${rvm_ruby_gem_home}/specifications/$(basename "$gem_file_name")spec" ]] ; then
    gem=""

    "$rvm_path/scripts/log" "info" \
      "$gem_name $gem_version exists, skipping (--force to re-install)"

  else
    if [[ -s "$gem" ]] ; then
      cache_file="$gem"

    elif [[ -s "$(__rvm_current_gemcache_dir)/${gem_file_name}" ]] ; then
      cache_file="$(__rvm_current_gemcache_dir)/${gem_file_name}"

    else
      cache_file="${cache_file:-$( find "$(__rvm_current_gemcache_dir)/${gem_file_name}" -maxdepth 1 -mindepth 1 -type f -print 2> /dev/null | sort | head -n1)}"
      cache_file="${cache_file//.\/}"
    fi

    if [[ ! -s "$cache_file" ]] ; then

      if [[ -s "$gem_file_name" ]] ; then
        gem="$gem_file_name"

      elif [[ -z "${gem_version// /}" ]] ; then
        gem="${gem_name// /}"

      else
        gem="${gem_name// /} -v $gem_version"
      fi
    else # cached

      gem_file_name="$(basename "$cache_file")"

      gem_string="$(echo "$gem_file_name" | sed 's#\.gem$##')"

      if [[ ${rvm_force_flag:-0} -eq 0 && -s "${rvm_ruby_gem_home}/specifications/$(basename $gem_file_name)spec" ]] ; then
        unset gem # already installed, not forcing reinstall.

        "$rvm_path/scripts/log" "info" "$gem_name $gem_version exists, skipping (--force to re-install)"

      else
        if [[ -s "$(__rvm_current_gemcache_dir)/$(basename $gem_file_name)" ]] ; then

          mkdir -p "${rvm_tmp_path:-"$rvm_path/tmp"}/$$/"

          mv "$(__rvm_current_gemcache_dir)/$gem_file_name" "${rvm_tmp_path:-"$rvm_path/tmp"}/$$/$gem_file_name"

          gem="${rvm_tmp_path:-"$rvm_path/tmp"}/$$/$gem_file_name -f -l"
        else
          gem="$cache_file"
        fi
      fi
    fi
  fi

  # If $gem is still set, go forward with the install.
  if [[ -n "$gem" ]] ; then

    # TODO: Set vars if fourth field is non-empty (means that there are conditional statements to execute in the gem install line.
    if [[ "rvm_make_flags_flag" -eq 1 ]] ; then __rvm_make_flags ; fi

    if [[ -n "$rvm_ruby_gem_home" && "$rvm_ruby_gem_home" != "${rvm_gems_path:-"$rvm_path/gems"}" ]] ; then

      command="GEM_HOME='$rvm_ruby_gem_home' GEM_PATH='$rvm_ruby_gem_home' BUNDLE_PATH='${rvm_ruby_gem_home}' $gem_prefix gem install $gems_args $rvm_gem_options $gem_postfix $vars"

    else

      #--ignore-dependencies
      command="$gem_prefix gem install --ignore-dependencies $gems_args $rvm_gem_options -q $gem $gem_postfix $vars"

    fi

    unset -f gem

    __rvm_run "gem.install" "$command" "installing ${gem_name} ${gem_version}..."
    result=$?

    if [[ $result -eq 0 ]] ; then

      "$rvm_path/scripts/log" "info" \
        "$gem_name $gem_version installed ( output logged to: $rvm_path/log/$rvm_ruby_string/gem.install.log )"

    else

      "$rvm_path/scripts/log" "error" \
        "$gem_name $gem_version failed to install ( output logged to: $rvm_path/log/$rvm_ruby_string/gem.install.error.log )"

    fi
  fi

  return $result
}

# Output the user's current gem directory.
gemset_info()
{
  if [[ ${rvm_user_flag:-0} -eq 1 ]] ; then
    echo $(rvm system ; gem env | grep "\- $HOME" | awk '{print $NF}')

  elif [[ ${rvm_system_flag:-0} -eq 1 ]] ; then
    echo $(rvm system ; gem env $action system)

  elif [[ -n "${rvm_ruby_string:-""}" ]] ; then
    echo $(rvm "$rvm_ruby_string" ; gem env $action)

  elif [[ -n "${GEM_HOME:-""}" ]] ; then
    echo "$GEM_HOME"

  else
    gem env $action
  fi

  return $?
}

gemset_prune()
{
  local temporary_cache_path live_cache_path gemset_name version versions cached_gem_name cached_file_path

  temporary_cache_path="$GEM_HOME/temporary-cache"

  live_cache_path="$GEM_HOME/cache"

  mkdir -p "$temporary_cache_path"

  "$rvm_path/scripts/log" "info" \
    "Moving active gems into temporary cache..."

  while read -r used_gem
  do
    gem_name="$(echo "$used_gem" | sed -e 's/ .*//')"

    versions="$(echo "${used_gem//, / }" | sed -e 's/.* (//' -e 's/)//')"

    for version in $versions; do

      cached_gem_name="${gem_name}-${version}.gem"

      cached_file_path="${live_cache_path}/${cached_gem_name}"

      if [[ -f "$cached_file_path" ]]; then
        mv "$cached_file_path" "${temporary_cache_path}/${cached_gem_name}"
      fi
    done
  done < <(gem list --versions)

  "$rvm_path/scripts/log" "info" \
    "Removing live cache and restoring temporary cache..."

  # Switch the cache back.
  rm -rf "$live_cache_path"

  mv "$temporary_cache_path" "$live_cache_path"

  return 0
}

gemset_pristine()
{
  if ( unset -f gem ; command -v gem > /dev/null ) ; then

    gem pristine --all

    return $?

  else

    "$rvm_path/scripts/log" "error" \
      "'gem' command not found in PATH"

    return 1
  fi
}

# Loads the default gemsets for the current interpreter and gemset.
gemset_initial()
{
  local gemsets gemset path paths

  rvm_gemsets_path="${rvm_gemsets_path:-"$rvm_path/gemsets"}"

  "$rvm_path/scripts/log" "info" \
    "Importing initial gemsets for $(__rvm_environment_identifier)."

  if [[ ! -d "$rvm_gemsets_path/${rvm_ruby_string//-//}" ]] ; then
    mkdir -p "$rvm_gemsets_path/${rvm_ruby_string//-//}" 2>/dev/null
  fi

  paths=($(__rvm_ruby_string_paths_under "$rvm_gemsets_path"))

  echo "paths: ${paths[@]}"

  for path in "${paths[@]}" ; do

    if [[ -n "$rvm_gemset_name" ]] ; then

      if [[ -s "${rvm_gemset_name}.gems" ]] ; then

        ( gems_args="${rvm_gemset_name}.gems" ; gemset_import )

      fi

    else

      if [[ -s "${path}/default.gems" ]] ; then

        ( gems_args="${path}/default.gems" ; gemset_import  )

      fi

      if [[ -s "${path}/global.gems" ]] ; then

        (
          rvm_create_flag=1
          rvm_ruby_gem_home="${rvm_ruby_gem_home//@*/}@global"
          gems_args="${path}/global.gems"
          gemset_import
        )

      fi

    fi

  done

  "$rvm_path/scripts/log" "info" \
    "Installation of gems for $(__rvm_environment_identifier) is complete."

  return 0
}

unset GEM_PATH

if ! command -v gem > /dev/null ; then
  "$rvm_path/scripts/log" "error" \
    "'gem' was not found, cannot perform gem actions (Do you have an RVM ruby selected?)"
  exit 1
fi

args=($*)
action="${args[$__array_start]}"
args[$__array_start]=""
args=(${args[@]})
gems_args="$(echo ${args[@]}) " # Strip trailing / leading / extra spacing.

export rvm_gemset_name="${args[1]:-""}" # For wherever used.
rvm_sticky_flag=1

if [[ -z "$rvm_ruby_string" ]] ; then

  if echo "${GEM_HOME:-""}" | grep -q 'rvm' ; then

    rvm_ruby_string="${GEM_HOME##*/}"

    rvm_ruby_string="${rvm_ruby_string%%@*}"

  fi

fi

case "$action" in

  import|load)

    if [[ -z "${rvm_ruby_strings:-""}" ]]; then

      gemset_import

    else
      original_env="$(__rvm_environment_identifier)"

      for rvm_ruby_string in $(echo "$rvm_ruby_strings" | tr "," " "); do

        __rvm_become

        gemset_import
      done

      __rvm_become "$original_env"

      unset original_env
    fi
    ;;
  export|dump)
    gemset_export
    ;;
  create)
    gemset_create
    ;;
  copy)
    gemset_copy
    ;;
  rename)
    gemset_rename
    ;;
  empty)
    gemset_empty
    ;;
  delete)
    gemset_delete
    ;;
  name|string)
    gemset_name
    ;;
  dir)
    gemset_dir
    ;;
  list)
    gemset_list
    ;;
  gemdir|gempath|gemhome|home|path|version)
    gemset_info
    ;;
  install)
    gem_install "$@"
    ;;
  pristine)
    gemset_pristine "$@"
    ;;
  initial)
    gemset_initial
    ;;
  prune)
    gemset_prune
    ;;
  update)
    gemset_update
    ;;
  unpack)
    gemset_unpack
    ;;
  globalcache)
    gemset_globalcache "$2"
    ;;
  clear)
    "$rvm_path/scripts/log" "info" "gemset cleared."
    exit 0
    ;;
  help)
    usage
    exit 0
    ;;
  *)
    usage
    exit 1
    ;;
esac

exit $?
