#!/usr/bin/env sh

NON_XDG_SYMLINKS="$NON_XDG_SYMLINKS"

set -e

if test -z "$DOTFILES"; then
  printf >&2 "The DOTFILES environment variable is not set!\n"
  exit 1
fi

NEW_STATE_TMP="$(mktemp -p /tmp symlinks.XXXXXX)"
cleanup() {
	rm -f "$NEW_STATE_TMP"
}
trap 'cleanup' EXIT

STATE_FILE="$DOTFILES/symlinks_state"
CONFIG_DIR="$DOTFILES/.config"
LOCAL_DIR="$DOTFILES/.local"

# Ensure the state file exists and is sorted
touch "$STATE_FILE"
sort -o "$STATE_FILE" "$STATE_FILE"

# Get a sorted list of in-repo config files as if they were in $HOME
CONFIG_FILES="$(cd "$(dirname "$CONFIG_DIR")" && find "$(basename "$CONFIG_DIR")" -type f)"
LOCAL_FILES="$(cd "$(dirname "$LOCAL_DIR")" && find "$(basename "$LOCAL_DIR")" -type f)"
FILES="$CONFIG_FILES $LOCAL_FILES $NON_XDG_SYMLINKS"
for CF in $FILES; do
	echo "$HOME/$CF" >> "$NEW_STATE_TMP"
done
sort -o "$NEW_STATE_TMP" "$NEW_STATE_TMP"

# Delete all files (if they are symlinks) that are in STATE_FILE and not in the repo
for TO_DELETE in $(comm -23 "$STATE_FILE" "$NEW_STATE_TMP"); do
	if test -L "$TO_DELETE"; then
		echo "Deleting symlink '$TO_DELETE'!"
		rm -f "$TO_DELETE"
	elif test -e "$TO_DELETE"; then
		echo "Not deleting '$TO_DELETE' as it's not a symlink!"
	else
		echo "Not deleting '$TO_DELETE' as it's already deleted?!"
	fi
done

# Link all files
for TO_LINK in $FILES; do
	if test ! -e "$HOME/$TO_LINK" || diff -q "$DOTFILES/$TO_LINK" "$HOME/$TO_LINK"; then
		echo "Linking '$TO_LINK' to '$HOME'!"
		mkdir -p "$(dirname "$HOME/$TO_LINK")"
		ln -sTf "$DOTFILES/$TO_LINK" "$HOME/$TO_LINK"
	else
		echo "Not overwriting '$HOME/$TO_LINK' with a symlink as a different file already exists on that path!"
	fi
done

# Update state file
sort "$NEW_STATE_TMP" > "$STATE_FILE"

cleanup
