#!/bin/bash
# $1 Full path to the installer (unused)
# $2 Location of the Homebrew installation we may need to move into place
# $3 Target install location (unused)
# $4 System root directory (unused)
set -euo pipefail

# Use system tools without triggering developer tool installation prompts.
export PATH="/usr/bin:/bin:/usr/sbin:/sbin"

script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" &>/dev/null && pwd -P)"
if [[ -f "${script_dir}/macos_user.sh" ]]
then
  # `pkgbuild` stages this helper beside the package scripts.
  # shellcheck disable=SC1091
  source "${script_dir}/macos_user.sh"
else
  # This fallback keeps direct local execution from the repository working.
  # shellcheck disable=SC1091
  source "${script_dir}/../../Library/Homebrew/utils/macos_user.sh"
fi

# disable analytics while installing
export HOMEBREW_NO_ANALYTICS_THIS_RUN=1
export HOMEBREW_NO_ANALYTICS_MESSAGE_OUTPUT=1

# verify the installation exists
# default to /opt/homebrew to make development/testing easier
homebrew_directory="${2:-/opt/homebrew}"
if [[ ! -d "${homebrew_directory:?}" ]]
then
  echo "No directory at ${homebrew_directory}!" >&2
  exit 1
fi

cd "${homebrew_directory}"

refuse_symlinked_directories() {
  for dir in Caskroom Cellar Frameworks bin etc include lib opt sbin share var var/homebrew var/homebrew/linked
  do
    if [[ -L "${dir}" ]]
    then
      echo "Refusing to operate on symlinked ${dir} in ${homebrew_directory}." >&2
      exit 1
    fi
  done
}

enter_managed_directory() {
  local directory="$1"
  local expected_path="$2"
  local display_path="$3"

  if [[ -L "${directory}" ]]
  then
    echo "Refusing to operate on symlinked ${display_path} in ${homebrew_directory}." >&2
    exit 1
  fi

  cd -P "${directory}"
  if [[ "$(pwd -P)" != "${expected_path}" ]]
  then
    echo "Refusing to operate on ${display_path} outside ${homebrew_directory}." >&2
    exit 1
  fi
}

prefix_directory="$(pwd -P)"

# optionally define an install user at /var/tmp/.homebrew_pkg_user.plist
# otherwise, get valid logged in user
homebrew_pkg_user="$(homebrew-package-user)" ||
  {
    echo "No valid user for Homebrew installation. Log in before install or specify an install user."
    exit 1
  }

if [[ "$(id -u "${homebrew_pkg_user}")" -eq 0 ]]
then
  echo "The Homebrew installation user must not be root."
  exit 1
fi

homebrew_pkg_group="admin"
if [[ " $(id -Gn "${homebrew_pkg_user}") " != *" admin "* ]]
then
  homebrew_pkg_group="$(id -gn "${homebrew_pkg_user}")"
fi
homebrew_pkg_mode="ug=rwx"
if [[ "${homebrew_pkg_group}" == staff ]]
then
  # Keep in sync with brew.sh and Homebrew/install's install.sh.
  umask go-w
  homebrew_pkg_mode="u=rwx,go-w"
  chmod -R go-w .
fi

# create missing directories
refuse_symlinked_directories
mkdir -vp Caskroom Cellar Frameworks etc include lib opt sbin share var
(
  enter_managed_directory var "${prefix_directory}/var" var
  mkdir -vp homebrew
  enter_managed_directory homebrew "${prefix_directory}/var/homebrew" var/homebrew
  mkdir -vp linked
)

if [[ -z "${HOMEBREW_NO_SUDO:-}" ]] && command -v sudo &>/dev/null
then
  user_command=(sudo -u "${homebrew_pkg_user}")
elif [[ "$(id -u)" == 0 ]]
then
  user_command=(homebrew-login "${homebrew_pkg_user}")
else
  echo "Switching to the Homebrew installation user without sudo requires root." >&2
  exit 1
fi

if [[ "${homebrew_pkg_group}" == staff ]]
then
  # Account-switching tools may reset the umask; retain both masks afterwards.
  # shellcheck disable=SC2016
  user_command+=(/bin/bash -c 'umask "$(printf "%03o" "$((8#$1 | 8#$(umask)))")"; shift; exec "$@"' -- "$(umask)")
fi

# set permissions
refuse_symlinked_directories
chmod -h "${homebrew_pkg_mode}" Caskroom Cellar Frameworks bin etc include lib opt sbin share var
(
  enter_managed_directory var "${prefix_directory}/var" var
  enter_managed_directory homebrew "${prefix_directory}/var/homebrew" var/homebrew
  chmod "${homebrew_pkg_mode}" .
  enter_managed_directory linked "${prefix_directory}/var/homebrew/linked" var/homebrew/linked
  chmod "${homebrew_pkg_mode}" .
)
chown -R "${homebrew_pkg_user}:${homebrew_pkg_group}" .

rm -rf "${homebrew_directory}/.git/hooks" "${homebrew_directory}/.gitconfig" "${homebrew_directory}/.config/git"
# The package already contains a stable checkout; reset it when Git is available.
if developer_dir="$(xcode-select --print-path 2>/dev/null)" &&
   [[ -n "${developer_dir}" && "${developer_dir}" != / && -x "${developer_dir}/usr/bin/git" ]]
then
  git_as_user() {
    "${user_command[@]}" /usr/bin/env \
      HOME="${homebrew_directory}" GIT_CONFIG_GLOBAL=/dev/null PATH="${PATH}" \
      "${developer_dir}/usr/bin/git" -c core.hooksPath=/dev/null "$@"
  }

  latest_tag="$(git_as_user -C "${homebrew_directory}" tag --list --sort="-version:refname" | head -n1)"
  git_as_user -C "${homebrew_directory}" checkout --force -B stable
  git_as_user -C "${homebrew_directory}" reset --hard "${latest_tag}"
  git_as_user -C "${homebrew_directory}" clean -f -d
fi

# move API cache to ~/Library/Caches/Homebrew
user_home_dir="$(homebrew-user-home "${homebrew_pkg_user}")" ||
  {
    echo "No home directory for Homebrew installation user: ${homebrew_pkg_user}"
    exit 1
  }
user_cache_dir="${user_home_dir}/Library/Caches/Homebrew"
user_api_cache_dir="${user_cache_dir}/api"
# Seed the cache as the install user: as root, `cp` follows a symlink planted at the
# destination, and the `chown -R` this removes would reach anything hard-linked into the tree.
"${user_command[@]}" mkdir -vp "${user_api_cache_dir}"
"${user_command[@]}" cp -vpR "${homebrew_directory}/cache_api/." "${user_api_cache_dir}"
if [[ "${homebrew_pkg_group}" == staff ]]
then
  "${user_command[@]}" chmod -R go-w "${user_cache_dir}"
fi
rm -vrf "${homebrew_directory}/cache_api"

# add Homebrew to the default PATH
if [[ -d "/etc/paths.d" ]]
then
  echo "${homebrew_directory}/bin" >/etc/paths.d/homebrew
  chown root:wheel /etc/paths.d/homebrew
fi
