#!/bin/bash
#
# Sets up Homebrew on this machine.
#
# THIS IS OUTDATED. Homebrew has changed their default installation location, setup
# process, and the whole Cask mechanism in the last few years (as of 2022). This script
# has not been updated for that yet. Also, the location of taps and Library under the
# Homebrew prefix has changed, and may vary between Intel and AS. Need to account for that.
#
# This script is (hopefully) idempotent, so you can rerun it on a machine that already
# has brew installed, though you may see (lots of) spurious warning messages. Each run
# does git fetches, so it requires a network connection even if everything is already set up.

# Load JXL. See "Loading JXL" in dots/README.md.
source "$(cd "$(dirname "$0")" && pwd -P)/../dots/all-os/flat/dotlib/jxl-lib.sh" \
    || { echo >&2 "ERROR: failed to load jxl-lib.sh"; exit 1; }

jxl::init_script
jxl::use_short_names

OPT_TRACE=0
NO_CASKS=0

function usage() {
  cat <<EOF
$PROGRAM_NAME - Set up Homebrew and some formulae on this machine.

Usage:
  $PROGRAM_NAME [--trace] [--no-casks]
  $PROGRAM_NAME --help

Options:
    -x, --trace     trace program execution
    -n, --no-casks  do not install any Casks
$(jxl::std_options_help)
EOF
}

function main() {
if [[ $OPT_TRACE = 1 ]]; then set -o xtrace; fi

THISDIR=$(dirname "${BASH_SOURCE[0]}")
my_brew_cfg_dir="$THISDIR/homebrew"

# Prerequisites

# Check for Xcode or CLT
if ! xcode-select -p >/dev/null; then
  cat >&2 <<EOF
ERROR: Neither Xcode nor Xcode CLT are installed. Please install one.

  To install Scode CLT:  sudo xcode-select --install
  To do Xcode:           Install Xcode and then run:
     sudo xcode-select -s /Applications/Xcode-<version>.app
EOF
  exit 1
fi

# Install Homebrew
if [[ -z $(which brew) ]]; then
  INSTALLER_URL='https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh'
  ruby -e "$(curl -fsSL $INSTALLER_URL)"
else
  echo "Homebrew is already installed. Not installing."
fi

# Pick what to install
if [[ -d "$my_brew_cfg_dir" ]]; then
  echo "Found brew config dir at: $my_brew_cfg_dir"
  _read_lines "$my_brew_cfg_dir/brew-taps-standard"
  taps=( ${_read_lines_out[@]+"${_read_lines_out[@]}"} )
  _read_lines "$my_brew_cfg_dir/brew-formulae-standard"
  formulae=( ${_read_lines_out[@]+"${_read_lines_out[@]}"} )
  _read_lines "$my_brew_cfg_dir/brew-casks-standard"
  casks=( ${_read_lines_out[@]+"${_read_lines_out[@]}"} )
  if [[ $NO_CASKS = 1 ]]; then
      casks=()
  fi
else
  echo "No brew config dir found at '$my_brew_cfg_dir'; using defaults."
  # Common defaults
  taps=( apjanke/personal adoptopenjdk/openjdk )
  formulae=( bash zsh wget dos2unix fortune git pstree tree watch )
  casks=()
fi

# Install taps
for tap in ${taps[@]+"${taps[@]}"}; do
  _do brew tap "$tap"
done

# Install formulae and casks

# Do casks first so Java gets picked up; it is a dependency of some formulae
for cask in ${casks[@]+"${casks[@]}"}; do
  _do brew install --cask "$cask"
done

_do brew install ${formulae[@]+"${formulae[@]}"}

echo ""
echo "Homebrew setup complete."

}

function parse_cli() {
  local arg

  while [[ $# -ge 1 ]]; do
    arg="$1"; shift
    case "$arg" in
      --trace | -x)                 OPT_TRACE=1 ;;
      --no-casks | -n)              NO_CASKS=1 ;;
      *)
        jxl::std_opt "$arg" \
            || die "Unexpected argument: ${arg}. See '$PROGRAM_NAME --help' for usage"
        if [[ $_JXL_WANT_HELP == 1 ]]; then usage; exit 0; fi
        ;;
    esac
  done

  readonly OPT_TRACE NO_CASKS
}

function _do() {
  echo "$@"
  "$@"
}

function _read_lines() {
  # Read FILE's non-blank lines into the global array $_read_lines_out.
  #
  # bash 3.2 (what /bin/bash is on macOS) has no mapfile, and `read -d ''` returns 1 at
  # EOF, which errexit catches. The `|| [[ -n ... ]]` picks up a last line that has no
  # trailing newline, which a plain `while read` drops silently.
  _read_lines_out=()
  local line
  while IFS= read -r line || [[ -n "$line" ]]; do
    if [[ -n "$line" ]]; then _read_lines_out+=("$line"); fi
  done < "$1"
}

# shellcheck disable=SC2329
function ensure_github_user_fork_remote() {
  local username="$1" repo="$2"
  if ! git remote get-url "$username" &>/dev/null; then
    _do git remote add "$username" "https://github.com/${username}/${repo}.git"
  fi
}

parse_cli "$@"
main
exit 0
