#!/bin/sh
#
# Purpose {{{
# This script will try to control MPD with mpc client command
#   1. Start MPD if not already running and disable random mode.
#   2. Send user command to MPD running instance.
#
# 2022-05-22
# }}}
# Vars {{{
PROGNAME=$(basename "${0}")
readonly PROGNAME
PROGDIR=$(readlink -m $(dirname "${0}"))
readonly PROGDIR
ARGS="${*}"
readonly ARGS
readonly NBARGS="${#}"
[ -z "${DEBUG}" ] && DEBUG=1
## Export DEBUG for sub-script
export DEBUG

## Default values for some vars
readonly MPD_PROC_REGEXP="mpd.*systemd"
readonly USER_MULTIMEDIA_COMMAND_DEFAULT="toggle"

## Colors
readonly PURPLE='\033[1;35m'
readonly RED='\033[0;31m'
readonly RESET='\033[0m'
readonly COLOR_DEBUG="${PURPLE}"
# }}}
usage() {                                                       # {{{

	cat <<- HELP
usage: $PROGNAME [-c|-d|-h]

Manage MPD with commands.

EXAMPLES :
    - Starts playing next song on the queue
        ${PROGNAME} --command next

    - Send default command (${USER_MULTIMEDIA_COMMAND_DEFAULT}) to MPD
        ${PROGNAME}

    - Start MPD if not already running and starts playing
        ${PROGNAME}

OPTIONS :
    -c,--command
        Send a command to running MPD. Available commands :
          * toggle, play, pause
          * next
          * previous
          * random
          * party, partymode, randomparty

    -d,--debug
        Enable debug messages.

    -h,--help
        Print this help message.
HELP

}
# }}}
debug_message() {                                               # {{{

	local_debug_message="${1}"

	## Print message if DEBUG is enable (=0)
	[ "${DEBUG}" -eq "0" ] && printf '\e[1;35m%-6b\e[m\n' "DEBUG − ${PROGNAME} : ${local_debug_message}"

	unset local_debug_message

	return 0
}
# }}}
error_message() {                                               # {{{

	local_error_message="${1}"
	local_error_code="${2}"

	## Print message
	printf '%b\n' "ERROR − ${PROGNAME} : ${RED}${local_error_message}${RESET}"

	exit "${local_error_code:=66}"
}
# }}}
define_vars() {                                                 # {{{

	## If USER_MULTIMEDIA_COMMAND wasn't defined (argument) {{{
	if [ -z "${USER_MULTIMEDIA_COMMAND}" ]; then
		## Use default value
		readonly USER_MULTIMEDIA_COMMAND="${USER_MULTIMEDIA_COMMAND_DEFAULT}"
	fi
	## }}}
	## Translate user command to MPD command {{{
	case "${USER_MULTIMEDIA_COMMAND}" in
		toggle )                              ## Toggle current play
			debug_message "defined − \
Use ${RED}MPC${COLOR_DEBUG} client for ${USER_MULTIMEDIA_COMMAND} command."
			MPD_COMMAND=$(mpc --quiet toggle)
			;;
		play )                                ## Starts playing song (default number 1)
			debug_message "defined − \
Use ${RED}MPC${COLOR_DEBUG} client for ${USER_MULTIMEDIA_COMMAND} command."
			MPD_COMMAND=$(mpc --quiet play)
			;;
		pause )                               ## Pauses playing
			debug_message "defined − \
Use ${RED}MPC${COLOR_DEBUG} client for ${USER_MULTIMEDIA_COMMAND} command."
			MPD_COMMAND=$(mpc --quiet pause)
			;;
		next )                                ## Starts playing next song on queue
			debug_message "defined − \
Use ${RED}MPC${COLOR_DEBUG} client for ${USER_MULTIMEDIA_COMMAND} command."
			MPD_COMMAND=$(mpc --quiet next)
			;;
		prev|previous )                       ## Starts playing previous song
			debug_message "defined − \
Use ${RED}MPC${COLOR_DEBUG} client for ${USER_MULTIMEDIA_COMMAND} command."
			MPD_COMMAND=$(mpc --quiet prev)
			;;
		random )                              ## Toggle random mode
			debug_message "defined − \
Use ${RED}MPC${COLOR_DEBUG} client for ${USER_MULTIMEDIA_COMMAND} command."
			MPD_COMMAND=$(mpc --quiet random)
			;;
		party|partymode|randomparty )         ## Start random playing
			debug_message "defined − \
Use multiple ${RED}MPC${COLOR_DEBUG} commands for ${USER_MULTIMEDIA_COMMAND} action."
			MPD_COMMAND=$(mpc --quiet clear; mpc --quiet random on; mpc --quiet add /; mpc --quiet play)
			;;
		* )                                   ## unknow option
			printf '%b\n' "${RED}Invalid MPD|MPC command: ${USER_MULTIMEDIA_COMMAND}${RESET}"
			printf '%b\n' "---"
			usage
			exit 1
			;;
	esac
	## }}}

}
# }}}
is_proc_absent() {                                             # {{{

	local_proc_pattern="${1}"

	## Proc is absent by default
	return_proc_absent="0"

	local_count_proc_pattern="$(pgrep -f -- "${local_proc_pattern}" | wc -l)"

	case "${local_count_proc_pattern}" in
		0 ) ## No procs related to this pattern are running
			return_proc_absent="0"
			;;
		* ) ## At least one proc seems running
			return_proc_absent="1"
			;;
esac

	## Simple debug message to valid current variables
	debug_message "is_proc_absent − \
procs running (with the pattern: ${RED}${local_proc_pattern}${COLOR_DEBUG}) on the current host: ${RED}${local_count_proc_pattern}${COLOR_DEBUG}."

	return "${return_proc_absent}"

}
# }}}

main() {                                                        # {{{

	## Define all vars
	define_vars

	## If MPD is not running {{{
	### AND Start it
	### AND exit 0
	is_proc_absent "${MPD_PROC_REGEXP}" \
		&& debug_message "Start ${RED}mpd with systemd${COLOR_DEBUG}." \
		&& systemctl --user start mpd.service \
		&& mpc --quiet random off \
		&& exit 0
	## }}}

	## Send MPD action to running instance {{{
	### And exit
	debug_message "Send ${RED}${USER_MULTIMEDIA_COMMAND}${COLOR_DEBUG} action to running MPD instance." \
		"${MPD_COMMAND}" \
		&& exit 0
	## }}}

}
# }}}

# Manage arguments                                                # {{{
# This code can't be in a function due to argument management

if [ ! "${NBARGS}" -eq "0" ]; then

	manage_arg="0"

	## If the first argument is not an option
	if ! printf -- '%s' "${1}" | grep -q -E -- "^-+";
	then
		## Print help message and exit
		printf '%b\n' "${RED}Invalid option: ${1}${RESET}"
		printf '%b\n' "---"
		usage

		exit 1
	fi

	# Parse all options (start with a "-") one by one
	while printf -- '%s' "${1}" | grep -q -E -- "^-+"; do

	case "${1}" in
		-c|--command )                        ## User command
			### Move to the next argument
			shift
			### Define var
			USER_MULTIMEDIA_COMMAND="${1}"
			;;
		-d|--debug )                          ## debug
			DEBUG=0
			;;
		-h|--help )                           ## help
			usage
			## Exit after help informations
			exit 0
			;;
		* )                                   ## unknow option
			printf '%b\n' "${RED}Invalid option: ${1}${RESET}"
			printf '%b\n' "---"
			usage
			exit 1
			;;
	esac

	debug_message "Arguments management − \
${RED}${1}${COLOR_DEBUG} option|command managed."

	## Move to the next argument
	shift
	manage_arg=$((manage_arg+1))

	done

	debug_message "Arguments management − \
${RED}${manage_arg}${COLOR_DEBUG} argument(s) successfully managed."
else
	debug_message "Arguments management − \
No arguments/options to manage."
fi

# }}}

main

exit 255