#!/usr/bin/env bash

requirements_find_osx_brew()
{
  if
    __rvm_which brew >/dev/null 2>&1
  then
    return 0
  else
    typeset __binary
    for __binary in ~/homebrew/bin/brew ~/.homebrew/bin/brew /usr/local/bin/brew
    do
      if
        [[ -f "${__binary}" && -s "${__binary}" && -x "${__binary}" ]]
      then
        PATH="$PATH:${__binary%/*}"
        return 0
      fi
    done
    return 1
  fi
}

requirements_osx_brew_version_list()
{
  if __rvm_which $1 >/dev/null
  then $1 --version 2>/dev/null | __rvm_sed -n -e '1{s/^.* //; p;}'
  fi
  ls -1 $( brew --cellar )/$1/ 2>/dev/null
}

requirements_osx_brew_lib_installed_prefix_check()
{
  brew_lib_prefix="$( brew --prefix "$1" 2>/dev/null )" &&
  [[ -n "${brew_lib_prefix}" && -d "${brew_lib_prefix}" ]] ||
  return $?
}

requirements_osx_brew_lib_installed()
{
  typeset brew_lib_prefix
  brew list -1 | __rvm_grep "^${1}$" >/dev/null &&
  requirements_osx_brew_lib_installed_prefix_check "$1" ||
  return $?
}

requirements_osx_brew_lib_available()
{
  brew search | __rvm_grep "^${1}$" >/dev/null || return $?
}

requirements_osx_brew_libs_install()
{
  brew unlink  "$@" || true # ignore: Error: No such keg: /usr/local/Cellar/automake
  brew install "$@" ||
  {
    typeset ret=$?
    rvm_warn "There were package installation errors, make sure to read the log.

Try \`brew tap --repair\` and make sure \`brew doctor\` looks reasonable.

Check Homebrew requirements https://github.com/mxcl/homebrew/wiki/Installation"
    case "$_system_version" in
      (10.6)
        rvm_warn "
On OSX 10.6 instead of command line tools install:
    https://github.com/downloads/kennethreitz/osx-gcc-installer/GCC-10.6.pkg"
        ;;
    esac
    return $ret
  }
}

requirements_osx_brew_check_custom()
{
  brew tap | __rvm_grep "$1" >/dev/null || __rvm_add_once packages_custom "$1"
}

requirements_osx_brew_install_custom()
{
  typeset __tap
  for __tap
  do brew tap "${__tap}" || return $?
  done
}

requirements_osx_brew_libs_outdated_filter()
{
  typeset IFS
  IFS="|"
  brew outdated --quiet | __rvm_grep -E "$*"
}

requirements_osx_brew_libs_try_upgrade()
{
  (( rvm_autolibs_flag_number > 0 )) || return 0

  typeset -a outdated_libs
  __rvm_read_lines outdated_libs <(
    requirements_osx_brew_libs_outdated_filter "$@"
  )
  if
    (( ${#outdated_libs[@]} ))
  then
    rvm_requiremnts_fail_or_run_action 2 \
      "Homebrew libs require update - skipping." \
      brew upgrade "${outdated_libs[@]}" ||
      return $?
  fi
}

requirements_osx_brew_libs_default_check_gcc42()
{
  if
    [[ " ${brew_libs[*]}" =~ "apple-gcc42" ]] && ! __rvm_which gcc-4.2 >/dev/null
  then
    rvm_error "
apple-gcc42 is not available in PATH, try:

    brew unlink apple-gcc42 && brew link apple-gcc42

and make sure that apple-gcc42 is available in your PATH:

    which gcc-4.2
"
    return 1
  fi
}

requirements_osx_brew_libs_set_path()
{
  typeset brew_lib brew_lib_prefix

  for brew_lib
  do
    if requirements_osx_brew_lib_installed_prefix_check "${brew_lib}"
    then __rvm_add_to_path prepend "${brew_lib_prefix}/bin"
    fi
  done
  rvm_debug "PATH=$PATH"
}

requirements_osx_brew_libs_configure()
{
  typeset package brew_lib brew_lib_prefix
  package="$1"
  shift

  for brew_lib
  do
    if requirements_osx_brew_lib_installed_prefix_check "${brew_lib}"
    then __rvm_update_configure_opt_dir "${package}" "${brew_lib_prefix}"
    fi
  done
}

requirements_osx_brew_after()
{
  (( ${#packages_installed[@]} == 0 )) ||
  requirements_osx_brew_libs_try_upgrade "${packages_installed[@]}" || return $?

  requirements_osx_brew_libs_default_check_gcc42                    || return $?
  requirements_osx_brew_libs_set_path       "${brew_libs[@]}"       || return $?
  requirements_osx_brew_libs_configure "$1" "${brew_libs_conf[@]}"  || return $?
  unset brew_libs brew_libs_conf

  case "$1" in
    (jruby*) true ;;
    (*) requirements_osx_brew_after_update_certs_openssl ;;
  esac
}

requirements_osx_brew_after_update_certs_openssl()
{
  typeset brew_lib_prefix
  if
    requirements_osx_brew_lib_installed_prefix_check openssl &&
    [[ -x "${brew_lib_prefix}/bin/openssl" ]]
  then
    rvm_requiremnts_fail_or_run_action 2 \
      "Skipping certificates update, make sure your certificates are up to date." \
      requirements_osx_update_openssl_cert "${brew_lib_prefix}/bin/openssl" || return $?
  else
    rvm_requiremnts_fail_always 2 \
      "Somehow it happened there is no executable 'openssl',
run 'brew doctor' and make sure latest 'openssl' is installed properly." ||
      return 12 # passing by 127 could be read as missing rvm.
  fi
}

requirements_osx_brew_libs_default_check_gcc()
{
  if
    requirements_detect_installed apple-gcc42 gcc46 gcc47 gcc48
  then
    case "${packages_installed[*]}" in
      (*gcc42*) export CC="$(brew --prefix apple-gcc42)/bin/gcc-4.2" ;;
      (*gcc46*) export CC="$(brew --prefix gcc46      )/bin/gcc-4.6" ;;
      (*gcc47*) export CC="$(brew --prefix gcc47      )/bin/gcc-4.7" ;;
      (*gcc48*) export CC="$(brew --prefix gcc48      )/bin/gcc-4.8" ;;
      (*)       return 1 ;;
    esac
  else
    return $?
  fi
}

requirements_osx_brew_libs_default_add_gcc_v_auto()
{
  if __rvm_version_compare "${_system_version}" -ge 10.7
  then requirements_osx_brew_libs_default_add_gcc_v 4.6
  else requirements_osx_brew_libs_default_add_gcc_v 4.2
  fi
}

requirements_osx_brew_libs_default_add_gcc_v()
{
  case "$1" in
    (4.2) requirements_osx_brew_libs_default_add_gcc "$2" gcc-4.2 apple-gcc42 homebrew/dupes    ;;
    (4.6) requirements_osx_brew_libs_default_add_gcc "$2" gcc-4.6 gcc46       homebrew/versions ;;
    (4.7) requirements_osx_brew_libs_default_add_gcc "$2" gcc-4.7 gcc47       homebrew/versions ;;
    (4.8) requirements_osx_brew_libs_default_add_gcc "$2" gcc-4.8 gcc48       homebrew/versions ;;
    (*)
      rvm_error "Do not know how to check/install gcc '$1'."
      return 1
      ;;
  esac
}

requirements_osx_brew_libs_default_add_gcc()
{
  if [[ -n "$1" ]] && __rvm_which "$1" >/dev/null
  then true
  else
    export CC="$2"
    if __rvm_which "$2" >/dev/null
    then true
    else
      if [[ -z "${3:-}" ]]
      then false           # no package known and binary not found
      else
        export CC="$(brew --prefix $3)/bin/$2"
        if [[ -x "$CC" ]]
        then true
        else
          if [[ -n "${4:-}" ]]
          then requirements_osx_brew_check_custom "$4"
          fi
          brew_libs+=( "$3" )
        fi
      fi
    fi
  fi
}

requirements_osx_brew_libs_default()
{
  brew_libs=(
    autoconf automake libtool pkg-config
  )
  # install gcc only if not yet available, prevents problems with gcc-4.2 on OSX 10.6
  typeset selected_compiler="$( __rvm_selected_compiler )"
  case "${selected_compiler:-}" in
    ("")
      case "$1" in
        (rbx*|rubinius*)
          if requirements_osx_brew_lib_installed llvm
          then brew_libs_conf=( llvm )
          fi
          ;;
        (*)
          __ruby_clang_ok "$1" ||
          requirements_osx_brew_libs_default_check_gcc ||
          requirements_osx_brew_libs_default_add_gcc_v_auto ||
          return $?
          ;;
      esac
      ;;
    (*gcc-4.2|*gcc-4.6|*gcc-4.7|*gcc-4.8)        # version                  full_path
      requirements_osx_brew_libs_default_add_gcc_v ${selected_compiler##*-} "${selected_compiler}" || return $?
      ;;
    (*)
      rvm_debug "No code to ensure that selected compiler: '${selected_compiler}' exists"
      ;;
  esac
  brew_libs_conf=( libyaml readline libksba )
  case "$1" in
    (ruby-1.8*|ree*)
      requirements_osx_brew_check_custom homebrew/versions
      brew_libs_conf+=( openssl098 )
      ;;
    (*)
      brew_libs_conf+=( openssl )
      ;;
  esac
  requirements_check "${brew_libs[@]}" "${brew_libs_conf[@]}" || return $?
}

requirements_osx_brew_define()
{
  case "$1" in
    (rvm)
      true
      ;;
    (jruby*)
      if
        is_head_or_disable_binary "$1"
      then
        __rvm_which git >/dev/null || requirements_check git
        if is_jruby_post17 "$1"
        then requirements_check_custom_after mvn=maven
        fi
      fi
      requiremnts_osx_java_fail  || return $?
      ;;
    (ir*)
      __rvm_which mono >/dev/null 2>&1 || return $?
      ;;
    (opal)
      requirements_check node
      ;;
    (ruby*head)
      __rvm_which git >/dev/null || requirements_check git
      requirements_osx_brew_libs_default "$1"
      requirements_version_minimal autoconf 2.67
      ;;
    (*-head)
      __rvm_which git >/dev/null || requirements_check git
      requirements_osx_brew_libs_default "$1"
      ;;
    (*)
      requirements_osx_brew_libs_default "$1"
      ;;
  esac
}

__CLT_version_at_least()
{
  typeset __version="$(
    pkgutil --pkg-info com.apple.pkg.DeveloperToolsCLI 2>/dev/null | __rvm_awk '$1~/version:/{print $2}'
  )"
  [[ -n "${__version}" ]] || return $?
  __rvm_version_compare "${__version}" -ge "$1" || return $?
}

requirements_osx_brew_update_system()
{
  if
    __rvm_version_compare "${_system_version}" -ge 10.7
  then
    __rvm_detect_xcode_version_at_least 4.6.2 ||
    __CLT_version_at_least 4.6.0 ||
    {
      typeset ret=$?
      rvm_error "
Xcode version older than 4.6.2 installed, download and install newer version from:

    http://connect.apple.com

After installation open Xcode, go to Downloads and install Command Line Tools.
"
      return $ret
    }
  fi
  brew update ||
  {
    typeset ret=$?
    rvm_error "Failed to update Homebrew, follow instructions here:
    https://github.com/mxcl/homebrew/wiki/Common-Issues
and make sure \`brew update\` works before continuing."
    return $ret
  }
}

requirements_osx_brew_install_brew_setup()
{
  if
    __rvm_version_compare "${_system_version}" -ge 10.5
  then
    homebrew_repo="mxcl/homebrew"
    homebrew_name="Homebrew"
  else
    homebrew_repo="mistydemeo/tigerbrew"
    homebrew_name="Tigerbrew"
  fi
  if
    (( UID == 0 )) && [[ -z "${SUDO_USER:-}" ]]
  then
    rvm_error "Requested installation of ${homebrew_name} but the process is running as 'root', make sure to run with 'sudo' from normal user and try again."
    return 1
  fi
  homebrew_home_default="/usr/local"
  printf "%b" "About to install ${homebrew_name}, press \`Enter\` for default installation in \`$homebrew_home_default\`,
type new path if you wish custom ${homebrew_name} installation (the path needs to be writable for user)\n: "
  read homebrew_home || return $?
  rvm_debug "homebrew_home=${homebrew_home:=$homebrew_home_default}"
}

requirements_osx_brew_install_brew_install()
{
  if
    [[ "${homebrew_home}" == "${homebrew_home_default}" ]]
  then
    if [[ -n "${SUDO_USER:-}" ]]
    then su - ${SUDO_USER} -c "ruby -e \"$(curl -fsSL https://raw.github.com/${homebrew_repo}/go)\"" || return $?
    else ruby -e "$(curl -fsSL https://raw.github.com/${homebrew_repo}/go)" || return $?
    fi
  else
    mkdir -p "${homebrew_home}" || return $?
    __rvm_curl https://github.com/${homebrew_repo}/tarball/master | tar xz --strip 1 -C "${homebrew_home}"
    __rvm_check_pipestatus ${PIPESTATUS[@]} ${pipestatus[@]} || return $?
    chmod +x "${homebrew_home}/bin/brew" # just in case
    if [[ -n "${SUDO_USER:-}" ]]
    then chown -R ${SUDO_USER} "${homebrew_home}"
    fi
  fi
  PATH="$PATH:${homebrew_home}/bin"
}

requirements_osx_brew_install_brew()
{
  typeset homebrew_home_default homebrew_home homebrew_repo homebrew_name

  requirements_osx_brew_install_brew_setup   || return $?
  requirements_osx_brew_install_brew_install || return $?
}

requirements_osx_brew_ensure_brew_available()
{
  __rvm_which brew >/dev/null ||
  {
    rvm_requiremnts_fail_or_run_action 2 \
      "Requested installation with homebrew libs, but homebrew is not available." \
      requirements_osx_brew_install_brew || return $?
  }
}

requirements_osx_brew_ensure_brew_can_install()
{
  # only check for 3+ (packages install, enabled)
  (( rvm_autolibs_flag_number > 2 )) || return 0

  typeset __celar_path
  __celar_path="$(brew --cellar)"
  if
    [[ ! -w "${__celar_path%/*}/bin" ]]
  then
    rvm_error "ERROR: '${__celar_path%/*}/bin' is not writable - it is required for Homebrew, try 'brew doctor' to fix it!"
    return 1
  elif
    [[ ! -w "${__celar_path}" && -e "${__celar_path}" ]]
  then
    rvm_error "ERROR: '${__celar_path}' is not writable - it is required for Homebrew, try 'brew doctor' to fix it!"
    return 1
  else
    rvm_debug "brew seems to be writable"
  fi
}

requirements_osx_brew_before()
{
  typeset -ax brew_libs brew_libs_conf
  requirements_osx_brew_ensure_brew_available   || return $?
  requirements_osx_brew_ensure_brew_can_install || return $?
}
