#!/bin/sh
set -eu

usage() {
	cat <<-'EOF'
		Usage:
		  player ACTION
		  player -h
	EOF
}

help() {
	cat <<-'EOF'


		Options:
		  -h, --help    show this message

		  ACTION        one of:
		                - backward:       go back 5 seconds
		                - forward:        go forward 5 seconds
		                - previous:       go to the previous track
		                - next:           go to the next track
		                - play-pause:     play/pause
		                - rotate:         rotate across available MPRIS players
		                - synopsis:       show the current MPRIS player and title
		                - synopsis-f:     show the current MPRIS player and title


		Manipulate the MPRIS audio player.


		Examples:

		  Change the current MPRIS player:

		    $ player synopsis


		  Play/pause:

		    $ player play-pause
	EOF
}


for flag in "$@"; do
	case "$flag" in
		(--)
			break
			;;
		(--help)
			usage
			help
			exit
			;;
		(*)
			;;
	esac
done

while getopts 'P:h' flag; do
	case "$flag" in
		(h)
			usage
			help
			exit
			;;
		(*)
			usage >&2
			exit 2
			;;
	esac
done
shift $((OPTIND - 1))
ACTION="${1:-}"

eval "$(assert-arg -- "$ACTION" 'ACTION')"



CURRENT_PLAYER_PATH="$XDG_CACHE_HOME"/euandreh-mpris-player.txt
CURRENT_PLAYER="$(cat "$CURRENT_PLAYER_PATH" 2>/dev/null ||:)"
AVAILABLE_PLAYERS="$(playerctl --list-all | LANG=POSIX.UTF-8 sort)"

pick_first() {
	printf '%s\n' "$AVAILABLE_PLAYERS" | head -n1
}

next_player() {
	if [ -z "$CURRENT_PLAYER" ]; then
		pick_first
	elif ! printf '%s\n' "$AVAILABLE_PLAYERS" | grep -q "$CURRENT_PLAYER"; then
		# Unknown $CURRENT_PLAYER, pick anyone
		pick_first
	else
		INDEX="$(printf '%s\n' "$AVAILABLE_PLAYERS" | grep -n "$CURRENT_PLAYER" | cut -d: -f1)"
		LENGTH="$(printf '%s\n' "$AVAILABLE_PLAYERS" | wc -l)"
		if [ "$INDEX" = "$LENGTH" ]; then
			# Reached the end of the $AVAILABLE_PLAYERS list, wrapping
			pick_first
		else
			# Get the next player instead
			printf '%s\n' "$AVAILABLE_PLAYERS" | awk -v idx="$INDEX" 'NR == idx+1 {print}'
		fi
	fi
}

format_player_name() {
	sed 's|^firefox\.instance.*$|firefox|'
}

formatted_player_title() {
	TITLE="$(
		playerctl --player="$CURRENT_PLAYER" metadata xesam:title \
			2>/dev/null ||:
		)"
	if [ -z "$TITLE" ]; then
		exit
		TITLE="$(
			playerctl --player="$CURRENT_PLAYER" metadata xesam:url |
				uri -d |
				sed 's|^.*/home/andreh/Downloads/||'
		)"
	fi
	if [ ${#TITLE} -gt 62 ]; then
		printf '%s...\n' "$(printf '%s' "$TITLE" | head -c 60)"
	else
		printf '%s\n' "$TITLE"
	fi
}

case "$ACTION" in
	backward)
		playerctl --player="$CURRENT_PLAYER" position 5-
		;;
	forward)
		playerctl --player="$CURRENT_PLAYER" position 5+
		;;
	previous)
		playerctl --player="$CURRENT_PLAYER" previous
		;;
	next)
		playerctl --player="$CURRENT_PLAYER" next
		;;
	play-pause)
		playerctl --player="$CURRENT_PLAYER" play-pause
		;;
	rotate)
		PLAYER="$(next_player)"
		printf '%s\n' "$PLAYER" > "$CURRENT_PLAYER_PATH"
		notify-send -t 1000 -- \
			"$(printf '%s' "$PLAYER" | format_player_name)" \
			'current MPRIS target'
		;;
	synopsis)
		printf '%s: %s\n' \
			"$(printf '%s\n' "$CURRENT_PLAYER" | format_player_name)" \
			"$(formatted_player_title)"
		;;
	synopsis-f)
		tail -f "$CURRENT_PLAYER_PATH" 2>/dev/null | format_player_name
		;;
	*)
		printf 'Bad ACTION: "%s".\n\n' "$ACTION" >&2
		usage >&2
		exit 2
		;;
esac
