#!/usr/bin/env bash
#
# Bootstrap for https://github.com/theintonerzero/dotfiles
#
#   curl -fsSL https://dl.darkovski.dev/git/dotfiles/install.sh | bash
#
# Clones the repository to ~/dotfiles (always there, whatever directory
# you happen to run this from), or updates it if it is already present,
# then hands over to the installer inside the repository.
#
# Use -fsSL rather than -s on the curl: without -f, curl prints an error
# page to stdout on a 404 and bash cheerfully executes it.

set -euo pipefail

REPO_URL="https://github.com/theintonerzero/dotfiles.git"
DEST="$HOME/dotfiles"
INSTALLER="install.sh"

say()  { printf '\033[1;34m==>\033[0m %s\n' "$1"; }
warn() { printf '\033[1;33m==>\033[0m %s\n' "$1" >&2; }
die()  { printf '\033[1;31mError:\033[0m %s\n' "$1" >&2; exit 1; }

# ---------------------------------------------------------------------------
# Prerequisites
# ---------------------------------------------------------------------------
if ! command -v git >/dev/null 2>&1; then
    case "$(uname -s)" in
    Darwin) hint="xcode-select --install" ;;
    Linux)
        if   command -v dnf     >/dev/null 2>&1; then hint="sudo dnf install -y git"
        elif command -v apt-get >/dev/null 2>&1; then hint="sudo apt-get install -y git"
        else hint="install git with your package manager"
        fi
        ;;
    *) hint="install git" ;;
    esac
    die "git is required but not installed. Try: $hint"
fi

# ---------------------------------------------------------------------------
# Fetch or update
# ---------------------------------------------------------------------------
if [ -e "$DEST" ]; then
    [ -d "$DEST" ] || die "$DEST exists but is not a directory. Move it and rerun."
    [ -d "$DEST/.git" ] || die "$DEST exists but is not a git repository. Move it and rerun."

    # Refuse to pull into somebody else's checkout sitting at the same path.
    origin="$(git -C "$DEST" remote get-url origin 2>/dev/null || echo '')"
    case "$origin" in
    *theintonerzero/dotfiles*) ;;
    "") die "$DEST is a git repository with no origin remote. Move it and rerun." ;;
    *)  die "$DEST already tracks $origin, not the dotfiles repository. Move it and rerun." ;;
    esac

    if [ -n "$(git -C "$DEST" status --porcelain)" ]; then
        # Local edits are almost always deliberate here, so stop rather
        # than stash or discard them.
        die "$DEST has uncommitted changes. Commit or stash them, then rerun."
    fi

    say "Updating $DEST"
    git -C "$DEST" pull --ff-only
else
    say "Cloning into $DEST"
    git clone --depth 1 "$REPO_URL" "$DEST"
fi

cd "$DEST"

[ -f "$INSTALLER" ] || die "No $INSTALLER in $DEST. The repository layout has changed."
[ -x "$INSTALLER" ] || chmod +x "$INSTALLER"

# ---------------------------------------------------------------------------
# Hand over
# ---------------------------------------------------------------------------
# Piping this script into bash leaves stdin pointing at the pipe, which is
# already consumed. sudo reads /dev/tty directly so its password prompt
# survives, but Homebrew's installer checks whether stdin is interactive
# and refuses to run without it. Reattach the real terminal when there is
# one, and fall back to telling Homebrew not to expect a human.
say "Running ./$INSTALLER"
# Testing with [ -r /dev/tty ] is not enough: the device node exists and
# reads as readable even with no controlling terminal, and the redirect
# then fails at the point of use with "Device not configured". Actually
# opening it in a subshell is the only reliable check.
if [ -t 0 ]; then
    exec "./$INSTALLER"
elif ( : < /dev/tty ) 2>/dev/null; then
    exec "./$INSTALLER" < /dev/tty
else
    warn "No terminal on stdin. Running non-interactively; prompts will be skipped."
    export NONINTERACTIVE=1
    exec "./$INSTALLER"
fi
