#!/usr/bin/env bash
# todo -- manage a to-do list

. lib.bash || exit
. ~/bin/lib/libks.bash || exit

date_fmt="'%y %b %_d"

lstodo() {
	if [[ -t 1 ]]; then
		nl -ba -s". " -w3 "$file" |
		grep -E "(-) (@$HOSTNAME\\W|[^@])|^[^-]+$" |
		sed -E $'
		s/(-) (.+) \+\+$/\\1 \e[1m\e[38;5;11m\\2\e[m/
		s/(-) (.+) \+$/\\1 \e[38;5;11m\\2\e[m/
		'
	else
		cat "$file"
	fi
}

showdiff() {
	diff \
		--old-line-format=$'- \e[38;5;9m%l\e[m\n' \
		--new-line-format=$'+ \e[38;5;10m%l\e[m\n' \
		--unchanged-line-format="" \
		"$@" || true
}

edit() {
	sed "$1" "$file" > "$file.tmp~" &&
	showdiff "$file" "$file.tmp~" &&
	cp "$file.tmp~" "$file" &&
	rm -f "$file.tmp~"
}

todo() {
	local arg=$*
	if [[ $arg == /* && $arg != ?*/?* && $arg != *\ * ]]; then
		if [[ $arg != /*/ ]]; then
			arg+='/'
		fi
		lstodo | sed -n "${arg}p"
	elif [[ $arg ]]; then
		echo "$(date +"$date_fmt") - $*" >> "$file"
		lstodo | tail -n 1
	elif [[ -s $file ]]; then
		lstodo
	fi
}

vitodo() {
	local arg=$*
	if [[ $arg == */* ]]; then
		edit "$arg"
	else
		eval "${EDITOR:-vi} \"\$file\""
	fi
}

rmtodo() {
	local pcmd dcmd addr
	if (( ! $# )); then
		set -- '$'
	fi
	for addr; do
		if [[ ! $addr ]]; then
			addr='$'
		elif [[ $addr == /* && $addr != /*/ ]]; then
			addr+='/'
		elif [[ $addr == *, ]]; then
			addr+='$'
		fi
		pcmd+="${addr}p;"
		dcmd+="${addr}d;"
	done
	lstodo | sed -n "$pcmd" && edit "$dcmd" >/dev/null
}

ks:find_file file= \
	~/todo \
	~/lib/todo \
	data:todo.txt ;

cmd=${0##*/}

case $cmd in
    todo|lstodo|vitodo|rmtodo)
	$cmd "$@";;
    *)
	todo;;
esac
