#!/usr/bin/env sh

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

if [ ! -d "$DOTFILES" ]
then
	printf >&2 "The DOTFILES path '%s' is not a directory!\n" "$DOTFILES"
	exit 1
fi

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

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

if [ ! -f "$NEW_STATE_TMP" ] || [ ! -w "$NEW_STATE_TMP" ]
then
	printf >&2 "Failed to create temporary file or it is not writable!\n"
	exit 1
fi

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

if [ ! -f "$STATE_FILE" ] || [ ! -w "$STATE_FILE" ]
then
	printf >&2 "Failed to create state file '%s' or it is not writable!\n" "$STATE_FILE"
	exit 1
fi

# Get a sorted list of in-repo config files as if they were in $HOME
CONFIG_DIR_DIRNAME="$(dirname "$CONFIG_DIR")"
CONFIG_DIR_BASENAME="$(basename "$CONFIG_DIR")"
LOCAL_DIR_DIRNAME="$(dirname "$LOCAL_DIR")"
LOCAL_DIR_BASENAME="$(basename "$LOCAL_DIR")"

CONFIG_FILES="$(cd "$CONFIG_DIR_DIRNAME" && find "$CONFIG_DIR_BASENAME" -type f)"
LOCAL_FILES="$(cd "$LOCAL_DIR_DIRNAME" && find "$LOCAL_DIR_BASENAME" -type f)"

ALL_FILES="$CONFIG_FILES $LOCAL_FILES $NON_XDG_SYMLINKS"
for CF in $ALL_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
STATE_FILE_EXCLUSIVES="$(comm -23 "$STATE_FILE" "$NEW_STATE_TMP")"
for TO_DELETE in $STATE_FILE_EXCLUSIVES
do
	if [ -L "$TO_DELETE" ]
	then
		printf >&2 "Deleting symlink '%s'!\n" "$TO_DELETE"
		rm -f "$TO_DELETE"
	elif [ -e "$TO_DELETE" ]
	then
		printf >&2 "Not deleting '%s' as it's not a symlink!\n" "$TO_DELETE"
	else
		printf >&2 "Not deleting '%s' as it's already deleted?!\n" "$TO_DELETE"
	fi
done

# Link all files
for TO_LINK in $FILES
do
	if [ ! -e "$HOME/$TO_LINK" ] || diff -q "$DOTFILES/$TO_LINK" "$HOME/$TO_LINK"
	then
		echo "Linking '$TO_LINK' to '$HOME'!"
		PARENT="$(dirname "$HOME/$TO_LINK")"
		mkdir -p "$PARENT"
		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
