#!/bin/sh

SOURCE="$(realpath "$0")"
STORE_PATH="$(dirname "$SOURCE")/../"
STORE_PATH="$(realpath "$STORE_PATH")"
STORE_ENTRIES_FILE="${STORE_PATH}/paths"
ABS_HOME="$(readlink -f "$HOME")"

method=""
path=""
do_commit=false
commit_message="."
pull_to=""
for arg in "$@"; do
    case $arg in
        "-c")
            do_commit=true
            ;;

        "-m="*)
            commit_message="${arg#*=}"
            ;;

        "-pt="*)
            pull_to="${arg#*=}"
            pull_to="$(realpath "$pull_to")"
            ;;

        *)
            if [ -z "$method" ]; then
                method="$arg"
            else
                path="$arg"
            fi
            ;;
    esac
done
if [ -z "$path" ]; then
	path="."
fi
path="$(realpath --no-symlinks "$path")"

add() {
    entry="$path"
    check-cyclical-entry
    check-duplicate-entry

	printf %s\\n "$entry" >> "$STORE_ENTRIES_FILE"
    printf %s\\n "Added path: $entry"
}

check-cyclical-entry() {
    case "$STORE_PATH" in
        "$entry"*)
            printf 'Cannot cyclically archive: "%s" contains dotfiles directory'\\n "$path" >&2
			exit
            ;;
    esac
}

check-duplicate-entry() {
    while IFS='' read -r line || [ -n "$line" ]; do
        case $entry in
         	"$line"*)
         	    printf %s\\n "Item already within path: ${line}" >&2
                exit
         		;;
        esac
    done < "$STORE_ENTRIES_FILE"
}

update-dest() {
    dest="$STORE_PATH/root$entry"
}

push() {
    while IFS='' read -r entry || [ -n "$entry" ]; do
        check-cyclical-entry

        update-dest
        dest_dir="$(dirname "$dest")"
		rsync -rv --itemize-changes "$entry" "$dest_dir"
    done < "$STORE_ENTRIES_FILE"
}

pull() {
    printf %s\\n "Diffs:"
    show-diff
    pull-prompt
}

entry-in-pull-path() {
    entry="${pull_to}${entry}"
}

pull-prompt() {
    printf "Is this ok? [y/N/d(etails)] "
    read -r response
    case "$response" in
        d*|D*)
            show-diff-detail
            pull-prompt
            ;;

        y*|Y*)
            confirmed-pull
            ;;

        *)
            printf %s\\n "No action taken"
            exit
            ;;
    esac
}

show-diff() {
    while IFS='' read -r entry || [ -n "$entry" ]; do
        update-dest
        entry-in-pull-path
        diff -rq "$entry" "$dest" | awk '
/^Only in/ { print $0 " (this will not be overwritten)"; next }
{ print }
'
    done < "$STORE_ENTRIES_FILE"
}

show-diff-detail() {
    while IFS='' read -r entry || [ -n "$entry" ]; do
        update-dest
        entry-in-pull-path
        diff -ru "$entry" "$dest"
    done < "$STORE_ENTRIES_FILE" | less
}

confirmed-pull() {
    while IFS='' read -r entry || [ -n "$entry" ]; do
        check-cyclical-entry

        update-dest
        entry-in-pull-path
        entry_dir="$(dirname "$entry")"
        mkdir -p "$entry_dir"
		rsync -rv --itemize-changes "$dest" "$entry_dir"
    done < "$STORE_ENTRIES_FILE"
}

case "$method" in
    "add") add ;;
    "remove") remove ;;
    "push") push ;;
    "pull") pull ;;
esac
